Register - Login
Views: 96133272
Main - Memberlist - Active users - Calendar - Wiki - IRC Chat - Online users
Ranks - Rules/FAQ - Stats - Latest Posts - Color Chart - Smilies
12-10-18 07:47:12 PM

Jul - The Cutting Room Floor - Shovel Knight - devmenu New poll - New thread - New reply
Next newer thread | Next older thread
wisk
Random nobody
Level: 5


Posts: 1/4
EXP: 319
For next: 210

Since: 07-28-14


Since last post: 4.0 years
Last activity: 3.0 years

Posted on 07-28-14 04:24:35 PM Link | Quote
Hi guys,

I spent some times reversing the game Shove Knight and found a hidden menu:



And a text viewer:



To reach this menu: open ShovelKnight.exe (md5:4efb1caf0dd0b4ba0c71c77c33768605) with an hex editor, and simply modify the byte located at 0x15f4cb from 0x40 to 0x5d. (don't forget to copy/rename the executable first).

I think there's more to find, but most of "interesting" files seem to be missing in the retail version.
einstein95
Member
Level: 35


Posts: 134/316
EXP: 255562
For next: 24374

Since: 04-11-13


Since last post: 71 days
Last activity: 61 days

Posted on 08-01-14 03:17:30 AM Link | Quote
Instead of an offset, could you give the 5 hex bytes before and after? That way it might be able to be found in later versions.
wisk
Random nobody
Level: 5


Posts: 2/4
EXP: 319
For next: 210

Since: 07-28-14


Since last post: 4.0 years
Last activity: 3.0 years

Posted on 08-01-14 04:02:56 PM (last edited by wisk at 08-01-14 04:05:10 PM) Link | Quote
Originally posted by einstein95
Instead of an offset, could you give the 5 hex bytes before and after? That way it might be able to be found in later versions.


Sure, it'll better with the asm code:



; function: 0055FED0
.text:005600A9 D9 EE fldz
.text:005600AB 89 47 08 mov [edi+8], eax
.text:005600AE D9 50 54 fst dword ptr [eax+54h]
.text:005600B1 D9 58 64 fstp dword ptr [eax+64h]
.text:005600B4 D9 80 A0 00 00 00 fld dword ptr [eax+0A0h]
.text:005600BA DC 25 08 FA 61 00 fsub ds:dbl_61FA08
.text:005600C0 D9 58 74 fstp dword ptr [eax+74h]
.text:005600C3 EB 02 jmp short loc_5600C7
.text:005600C5 ; ---------------------------------------------------------------------------
.text:005600C5
.text:005600C5 loc_5600C5: ; CODE XREF: sub_55FED0+187j
.text:005600C5 33 FF xor edi, edi
.text:005600C7
.text:005600C7 loc_5600C7: ; CODE XREF: sub_55FED0+1F3j
.text:005600C7 8B 75 F8 mov esi, [ebp+var_8]
.text:005600CA 6A 40 push 40h ; TitleScreenID
.text:005600CC E8 9F 33 04 00 call SK_SetId ; init the second id
.text:005600CC ; update id
.text:005600D1 8B 4D FC mov ecx, [ebp+var_4]
.text:005600D4
.text:005600D4 loc_5600D4: ; CODE XREF: sub_55FED0+C8j
.text:005600D4 ; sub_55FED0+D5j
.text:005600D4 8D 79 58 lea edi, [ecx+58h]
.text:005600D7 C7 45 F8 07 00 00 00 mov [ebp+var_8], 7
.text:005600DE 8B FF mov edi, edi




Basically, SK_SetId (005A3470) sets the given argument to a global variable. The patch modifies the argument (005600CA + 1) from 0x40 (TitleScreenID) to 0x5D (DevMenuId).



;function: 005A3470 (SK_SetId)
.text:005A34B5 8B 45 08 mov eax, [ebp+DataId]
.text:005A34B8 A3 10 6D 63 00 mov g_SK_NextId



This ID is then copied to another global variable:



; function: 005A3050
.text:005A3152 8B 15 10 6D 63 00 mov edx, g_SK_NextId
.text:005A3158 8B 0D 0C 6D 63 00 mov ecx, g_SK_CurId
.text:005A315E 89 35 10 6D 63 00 mov g_SK_NextId, esi
.text:005A3164 8B 35 2C 42 5F 00 mov esi, ds:SDL_GetTicks
.text:005A316A 89 0D 14 6D 63 00 mov dword_636D14, ecx
.text:005A3170 89 15 0C 6D 63 00 mov g_SK_CurId



Finally, this ID is used to fetch an entry from a global array of structure which contains every "scenes" of the game:



; function: 0048A4E0
.text:0048A4EC A1 0C 6D 63 00 mov eax, g_SK_CurId
.text:0048A4F1 56 push esi ; Args
.text:0048A4F2 8B 35 E4 40 5F 00 mov esi, ds:sprintf
.text:0048A4F8 8D 04 40 lea eax, [eax+eax*2]
.text:0048A4FB 8B 0C C5 08 80 62 00 mov ecx, dword ptr g_DataEntries.Name[eax*8]



In this case, we're looking for 0x5D because it contains the entry "Dev Init".



.data:00628008 dd offset aDevInit ; [5Dh].Name
.data:00628008 dd 0 ; [5Dh].PakPath
.data:00628008 dd offset byte_5FF6FE ; [5Dh].DataPath
.data:00628008 dd offset aDev ; [5Dh].Type
.data:00628008 dd 2 ; [5Dh].anonymous_4
.data:00628008 dd 0 ; [5Dh].anonymous_5



There's more way to access this devmenu, but I think this one is the cleaner.
Tell me if you need further info.

BTW, the PC version contains references to StreetPass:

einstein95
Member
Level: 35


Posts: 135/316
EXP: 255562
For next: 24374

Since: 04-11-13


Since last post: 71 days
Last activity: 61 days

Posted on 08-02-14 08:35:21 AM (last edited by einstein95 at 08-02-14 08:46:50 AM) Link | Quote
Whoa, didn't expect that! In the latest gog.com version, (MD5: f06634861076e2af96f4caf122b72b54) the byte is at offset 0x15EAEB.

In addition to Streetpass references, in the menu text (line 74) there's the option "MIIVERSE FUNCTIONS" in addition to 79 and 80 being "SPOTPASS" and "MIIVERSE" respectively. Line 130+ all start with (COMMUNITY_) (130 is [sic] "MIIVERSE FUNCTIONS ARE UNAVALIABLE"), and describe the "Digger's Diary" which is the Miiverse stuff.

Edit: Oh, turns out the 3DS version was released on the 26th June.
jedivulcan
Member
Level: 16


Posts: 23/53
EXP: 20009
For next: 247

Since: 07-31-11


Since last post: 1.0 years
Last activity: 32 days

Posted on 08-02-14 01:48:38 PM Link | Quote
Originally posted by einstein95
Whoa, didn't expect that! In the latest gog.com version, (MD5: f06634861076e2af96f4caf122b72b54) the byte is at offset 0x15EAEB.

In addition to Streetpass references, in the menu text (line 74) there's the option "MIIVERSE FUNCTIONS" in addition to 79 and 80 being "SPOTPASS" and "MIIVERSE" respectively. Line 130+ all start with (COMMUNITY_) (130 is [sic] "MIIVERSE FUNCTIONS ARE UNAVALIABLE"), and describe the "Digger's Diary" which is the Miiverse stuff.

Edit: Oh, turns out the 3DS version was released on the 26th June.


Neither the 3DS or Wii U versions have SpotPass functionality as far as I can tell. 3DS has the aforementioned StreetPass functionality. The games I've used on Wii U that have SpotPass are Pikmin 3, Pushmo World, and New Super Mario Bros. U.

Maybe SpotPass was either scrapped or part of an upcoming update for Nintendo platforms?

Ehm
Member
Level: 47


Posts: 448/533
EXP: 724549
For next: 41654

Since: 06-13-09

From: Canada

Since last post: 224 days
Last activity: 217 days

Posted on 08-02-14 01:56:15 PM Link | Quote
It could easily be an upcoming feature. The developers said they still have to add stretch goal content to all platform versions of the game.
einstein95
Member
Level: 35


Posts: 136/316
EXP: 255562
For next: 24374

Since: 04-11-13


Since last post: 71 days
Last activity: 61 days

Posted on 08-02-14 02:09:30 PM Link | Quote
One thing I was going to say before computer crashed: It appears that at least one debug utility (Treasure ID) requires the pak files to be extracted in the data folder, which can easily be done with this BMS script and quickbms:


# Распаковка *.pak для игры Shovel Knight
# for %i in (*.pak) do quickbms pak.bms %i
get ident long
if ident != 0
cleanexit
endif
get files long
if files == 0
cleanexit
endif
get adr_tab_data longlong
get adr_tab_name longlong
for i = 0 < files
goto adr_tab_name
get adr_name longlong
savepos adr_tab_name
goto adr_name
getct name_block string 0
goto adr_tab_data
get adr_data longlong
savepos adr_tab_data
goto adr_data
get size_block longlong
get dummy longlong
get dummy longlong
get dummy longlong
savepos offset
log name_block offset size_block
next i



The NSB files can be opened with this extractor, revealing all the sounds and music to be mp3s.
wisk
Random nobody
Level: 5


Posts: 3/4
EXP: 319
For next: 210

Since: 07-28-14


Since last post: 4.0 years
Last activity: 3.0 years

Posted on 08-03-14 11:10:48 AM Link | Quote
Regarding the SpotPass/miiverse feature, I didn't find anything about it in the Steam version.
The only reference I found is the path "menus/miiverse.anb" which, of course, is missing.

About the PAK file format, too bad I suck at googling I did one myself in python (available here).
./pak_extract.py -out dump *.pak extracts all files contained in PAK to the folder dump.

Finally, I found what I was looking for: the hidden console!




And the collision viewer (cmd: drawattack 7):



To enable the console, I've made a really hackish patch:



; function: 00E1A660
.text:005BA6C3 66 89 1D 10 E2 62 00 mov word_62E210, bx
.text:005BA6CA D9 45 0C fld [ebp+arg_4]
.text:005BA6CD 89 1D 18 E7 62 00 mov dword_62E718, ebx
.text:005BA6D3 D9 1D 34 15 63 00 fstp flt_631534
.text:005BA6D9 89 1D F0 DF 62 00 mov dword_62DFF0, ebx
.text:005BA6DF D9 45 10 fld [ebp+arg_8]
.text:005BA6E2 88 1D 5A 0C 63 00 mov g_ShowConsole, bl
.text:005BA6E8 D9 1D 38 15 63 00 fstp flt_631538
.text:005BA6EE 88 1D 5B 0C 63 00 mov byte_630C5B, bl
.text:005BA6F4 D9 45 14 fld [ebp+arg_C]
.text:005BA6F7 88 1D 59 0C 63 00 mov byte_630C59, bl
.text:005BA6FD D9 1D 3C 15 63 00 fstp flt_63153C
.text:005BA703 C6 05 64 0C 63 00 01 mov byte_630C64, 1
.text:005BA70A D9 45 18 fld [ebp+arg_10]
.text:005BA70D 89 1D 68 0C 63 00 mov dword_630C68, e



You have to force the value g_ShowConsole to be different from 0. To do so, you can change the byte 005BA6E2 + 1 (MOV Ev, Eg Mod/RM) from 1D to 2D. This modification changes the source register from bl (which is zero) to ch (ECX[16:8]), which contains a pointer. The register ch *should* always be different from 0.

It would be better to bind a key (like ~) to the console.

Happy digging!
jedivulcan
Member
Level: 16


Posts: 24/53
EXP: 20009
For next: 247

Since: 07-31-11


Since last post: 1.0 years
Last activity: 32 days

Posted on 08-03-14 02:17:28 PM Link | Quote
Originally posted by wisk
Regarding the SpotPass/miiverse feature, I didn't find anything about it in the Steam version.
The only reference I found is the path "menus/miiverse.anb" which, of course, is missing.

About the PAK file format, too bad I suck at googling I did one myself in python (available here).
./pak_extract.py -out dump *.pak extracts all files contained in PAK to the folder dump.

Finally, I found what I was looking for: the hidden console!




And the collision viewer (cmd: drawattack 7):



To enable the console, I've made a really hackish patch:



; function: 00E1A660
.text:005BA6C3 66 89 1D 10 E2 62 00 mov word_62E210, bx
.text:005BA6CA D9 45 0C fld [ebp+arg_4]
.text:005BA6CD 89 1D 18 E7 62 00 mov dword_62E718, ebx
.text:005BA6D3 D9 1D 34 15 63 00 fstp flt_631534
.text:005BA6D9 89 1D F0 DF 62 00 mov dword_62DFF0, ebx
.text:005BA6DF D9 45 10 fld [ebp+arg_8]
.text:005BA6E2 88 1D 5A 0C 63 00 mov g_ShowConsole, bl
.text:005BA6E8 D9 1D 38 15 63 00 fstp flt_631538
.text:005BA6EE 88 1D 5B 0C 63 00 mov byte_630C5B, bl
.text:005BA6F4 D9 45 14 fld [ebp+arg_C]
.text:005BA6F7 88 1D 59 0C 63 00 mov byte_630C59, bl
.text:005BA6FD D9 1D 3C 15 63 00 fstp flt_63153C
.text:005BA703 C6 05 64 0C 63 00 01 mov byte_630C64, 1
.text:005BA70A D9 45 18 fld [ebp+arg_10]
.text:005BA70D 89 1D 68 0C 63 00 mov dword_630C68, e



You have to force the value g_ShowConsole to be different from 0. To do so, you can change the byte 005BA6E2 + 1 (MOV Ev, Eg Mod/RM) from 1D to 2D. This modification changes the source register from bl (which is zero) to ch (ECX[16:8]), which contains a pointer. The register ch *should* always be different from 0.

It would be better to bind a key (like ~) to the console.

Happy digging!


I can't try this out myself because I don't have the Steam or GoG version of the game and this stuff is a bit over my head.

How do the cheats in the console correlate to cheats that can be entered when I begin a new game? For example, that screenshot you posted shows "butt" to enable butt mode in the console ... but it can be enabled from the name select by typing X&BUTT or WSWWAEAW. I wonder if the console can reveal the effects of codes that are still unknown if they aren't a placeholder for codes that will be utilized in future updates.
wisk
Random nobody
Level: 5


Posts: 4/4
EXP: 319
For next: 210

Since: 07-28-14


Since last post: 4.0 years
Last activity: 3.0 years

Posted on 08-03-14 03:52:27 PM (last edited by wisk at 08-03-14 04:01:04 PM) Link | Quote
Originally posted by jedivulcan
How do the cheats in the console correlate to cheats that can be entered when I begin a new game? For example, that screenshot you posted shows "butt" to enable butt mode in the console ... but it can be enabled from the name select by typing X&BUTT or WSWWAEAW. I wonder if the console can reveal the effects of codes that are still unknown if they aren't a placeholder for codes that will be utilized in future updates.



That's an interesting question.

All I can tell you is that there's a global variable, say g_ButtMode, which can be enable or disable.
If this variable is enabled, it replaces knight, shovel, health and magic with butt:

(addresses are rebased due to ASLR)


.text:00DC1AD6 mov cl, g_ButtMode
.text:00DC1ADC and cl, 1
.text:00DC1ADF jz butt_mode_is_disabled
.text:00DC1AE5 push offset aButt ; "butt"
.text:00DC1AEA push offset aKnight ; "knight"
.text:00DC1AEF lea esi, [esp+938h+Source]
.text:00DC1AF6 call TextReplace
.text:00DC1AFB push offset aButt_0 ; "Butt"
.text:00DC1B00 push offset aKnight_0 ; "Knight"
.text:00DC1B05 call TextReplace
.text:00DC1B0A push offset aButt_0 ; "Butt"
.text:00DC1B0F push offset aShovel_0 ; "Shovel"
.text:00DC1B14 call TextReplace
.text:00DC1B19 push offset aButt ; "butt"
.text:00DC1B1E push offset aShovel ; "shovel"
.text:00DC1B23 call TextReplace
.text:00DC1B28 push offset aButt_0 ; "Butt"
.text:00DC1B2D push offset aHealth ; "Health"
.text:00DC1B32 call TextReplace
.text:00DC1B37 push offset aButt ; "butt"
.text:00DC1B3C push offset aHealth_0 ; "health"
.text:00DC1B41 call TextReplace
.text:00DC1B46 push offset aButt_0 ; "Butt"
.text:00DC1B4B push offset aMagic ; "Magic"
.text:00DC1B50 call TextReplace
.text:00DC1B55 push offset aButt ; "butt"
.text:00DC1B5A push offset aMagic_0 ; "magic"
.text:00DC1B5F call TextReplace
.text:00DC1B64 add esp, 40h
.text:00DC1B67
.text:00DC1B67 butt_mode_is_disabled: ; CODE XREF: sub_DC14F0+5E0j
.text:00DC1B67 ; sub_DC14F0+5EFj
;...



I can find only one place where this variable is directly written:



.text:00DBB7E0 loc_DBB7E0: ; CODE XREF: ycConsole__Cmd_butt+1Cj
.text:00DBB7E0 A2 D4 45 E9 00 mov g_ButtMode, al
.text:00DBB7E5 84 C9 test cl, cl
.text:00DBB7E7 74 17 jz short loc_DBB800
.text:00DBB7E9 24 01 and al, 1
.text:00DBB7EB 74 13 jz short loc_DBB800
.text:00DBB7ED 68 50 00 E7 00 push offset aButtModeIsOn ; "Butt mode is ON!"
.text:00DBB7F2 E8 49 ED 05 00 call ycConsole__Printf_
.text:00DBB7F7 83 C4 04 add esp, 4
.text:00DBB7FA 8B E5 mov esp, ebp
.text:00DBB7FC 5D pop ebp
.text:00DBB7FD C2 04 00 retn 4



This is the handler of the command "butt".

But! And thank you for giving me these cheat codes, I managed to understand how cheat code are handled in game. Basically, the Shovel Knight uses a hash function (it takes a string in parameter and returns a 32-bit value).
This function is usually used to increase performance (see hash table).
In this case, it's used to hash the player name, which is compared to a list of hash value:



.text:00D46059 push eax
.text:00D4605A call __SK_Hash
.text:00D4605F add esp, 4
.text:00D46062 pop esi
.text:00D46063 test eax, eax
.text:00D46065 jz short loc_D46088
.text:00D46067 xor ecx, ecx
.text:00D46069 lea esp, [esp+0]
.text:00D46070
.text:00D46070 loc_D46070: ; CODE XREF: SK_IsNameCheatCode+46j
.text:00D46070 mov edx, HashedCheatCode[ecx*4]
.text:00D46077 test edx, edx
.text:00D46079 jz short loc_D4607F
.text:00D4607B cmp edx, eax
.text:00D4607D jz short loc_D4608C
.text:00D4607F
.text:00D4607F loc_D4607F: ; CODE XREF: SK_IsNameCheatCode+39j
.text:00D4607F inc ecx
.text:00D46080 cmp ecx, 141h
.text:00D46086 jl short loc_D46070



That's explain why one cheat can be unlocked using multiple names (see hash collision).

Using the index from HashedCheatCode array, a huge switch is used to apply hardcoded cheat (I can't paste the code but I could provide more info if you want to look by yourself).

I can't guarantee all cheat codes have been found, you have to bruteforce them to find them all.

BTW, by messing cheat codes values, I found a challenge mode. I already finished the game once (not game+), but I've never seen it before.
Is this mode hidden?
EDIT: this video answers this question. The challenge mode is unlocked using the cheatcode IM&SGC14.




This game is really awesome: the more you search, the more you find something new.

PS: Sorry for the long post.
Ehm
Member
Level: 47


Posts: 449/533
EXP: 724549
For next: 41654

Since: 06-13-09

From: Canada

Since last post: 224 days
Last activity: 217 days

Posted on 08-03-14 04:02:51 PM Link | Quote
According to the latest Kickstarter update, Challenge Mode has yet to be implemented.


What are we working on right now, you ask? Well, we’re in the middle of:

- Embarking upon stretch goal content: boss campaigns, challenge mode, gender swap, and battle mode!!



Might be cool to see if any of the other features are partially implemented. The four-player battle mode is only coming to PC/Wii U from what I understand.
Ehm
Member
Level: 47


Posts: 450/533
EXP: 724549
For next: 41654

Since: 06-13-09

From: Canada

Since last post: 224 days
Last activity: 217 days

Posted on 08-03-14 04:49:12 PM Link | Quote
Actually, it looks like that Challenge Mode is just a taste of what's to come (unless there's more than the one level).
The password references the Iron Man of Gaming event at the Screwattack Gaming Convention that just took place.
SMK
Random nobody
Level: 3


Posts: 1/2
EXP: 112
For next: 16

Since: 08-03-14


Since last post: 4.0 years
Last activity: 2.0 years

Posted on 08-03-14 10:18:52 PM Link | Quote
if you want to enable the console on the newest gog version (MD5: f06634861076e2af96f4caf122b72b54) the byte is at offset 0x1B8DD3
Hiccup
Member
Disgustingly Naive Smartass
Level: 54


Posts: 438/753
EXP: 1221099
For next: 12771

Since: 05-19-09


Since last post: 8 days
Last activity: 3 hours

Posted on 10-12-14 08:55:52 AM Link | Quote
Does anybody know how to unpack the anb files (and is willing to share the information) ?
einstein95
Member
Level: 35


Posts: 152/316
EXP: 255562
For next: 24374

Since: 04-11-13


Since last post: 71 days
Last activity: 61 days

Posted on 10-12-14 02:13:53 PM Link | Quote
Originally posted by Hiccup
Does anybody know how to unpack the anb files (and is willing to share the information) ?

Google it
GoldS
Member
Level: 39


Posts: 305/366
EXP: 395623
For next: 9148

Since: 03-15-10


Since last post: 197 days
Last activity: 22 min.

Posted on 10-12-14 04:10:15 PM (last edited by GoldS at 10-12-14 04:10:53 PM) Link | Quote
Originally posted by Hiccup
Does anybody know how to unpack the anb files (and is willing to share the information) ?

For an actual answer to your question, apparently the program here will decompress the files: Here.

Exectuable located Here.

Don't ask me how the program works because I don't know.
Hiccup
Member
Disgustingly Naive Smartass
Level: 54


Posts: 439/753
EXP: 1221099
For next: 12771

Since: 05-19-09


Since last post: 8 days
Last activity: 3 hours

Posted on 10-13-14 07:55:27 AM (last edited by Hiccup at 10-13-14 08:00:16 AM) Link | Quote
Thank you.

And, yes I could have googled 'DuckTales anb'.
KartMario
Member
Level: 13


Posts: 26/29
EXP: 8307
For next: 1960

Since: 03-13-11


Since last post: 77 days
Last activity: 1.0 years

Posted on 12-26-16 09:44:57 PM Link | Quote
A bit of a bump. but does anyone know the address for the most recent Steam version?
Next newer thread | Next older thread
Jul - The Cutting Room Floor - Shovel Knight - devmenu New poll - New thread - New reply




Rusted Logic

Acmlmboard - commit 220d144 [2018-11-04]
©2000-2018 Acmlm, Xkeeper, Inuyasha, et al.

35 database queries, 10 query cache hits.
Query execution time: 0.162850 seconds
Script execution time: 0.041019 seconds
Total render time: 0.203869 seconds