http://atom0s.com
Posts: 154
|
Post by atom0s on Jan 29, 2015 17:44:51 GMT 10
Config.ini - The Game Settings The game uses a file called Config.ini to store the settings for the game. This file is located in your AppData folder, for example: C:\Users\atom0s\AppData\Local\CAPCOM\Resident Evil - biohazard@hd REMASTER\config.ini
This file has various configurations for the graphics, the joypad, and more.
Various Addresses Here are some addresses for various information in the game: [0xDE464C] + 0x20 (byte) - Enable / Disable XInput [0xDE5340] - Client Window hData (Start of structure.) [0xDE5340] + 0x12C - Game Hwnd [0xDE5340] + 0x130 - Game Hwnd (Sub) [0xDE5340] + 0x2551 - Game Window Has Focus [0xDE5340] + 0x2553 - Game Install Path (?) [0xDE5340] + 0x2698 - Left button down on window caption bar.
[[0xDE41BC] + 0x14C] - Current player pointer. Points to the start of the player information structure. [[0xDE41BC] + 0x14C] + 0x13BC - Player current health. [[0xDE41BC] + 0x14C] + 0x13C0 - Player maximum health.
[0xD7C9C0] - Inventory structure pointer. (Item entries start at + 0x38) [0xD7C9C0] + 0x5110 - Inventory size adjustment. (0 = 6, 1 = 8) [Warning, editing this will fuck up your character!] [0xD7C9C0] + 0x5114 - Current costume. This can be changed freely and game will update costume when you enter a new room. (0...3) [0xD7C9C0] + 0x5118 - Current character. This can be changed freely and game will update character when you enter a new room. (0 = Chris, 1 = Jill, 2 = Rebecca)
[0xD7C9C0] + 0x5124 - Unlockables (bitflags) [0xD7C9C0] + 0xE474C - Total time played. [0xD7C9C0] + 0xE476C - Total save count. [0xD7C9C0] + 0xE4778 - Total shots fired.
[0xDE4248] + 0x38 - The fps cap for the game. [0xDE4248] + 0x3C - The current in-game fps divisor. (Seems to be always 30 currently). [0xDE4248] + 0x44 - The current in-game fps.
Function Addresses sub_48B6B0((void *)dword_D7C9C0, 0xAu); -- Causes the player to die / game over. int __stdcall sub_72E520(int a1) - Handles the XInput buffer information. int __stdcall sub_72ED50(int a1, int a2) - Handles the XInput buffer information.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Jan 31, 2015 10:35:24 GMT 10
Here is all the valid values for the games Config.ini taken from the games memory:
JobThread - 0040 RenderingThread - 0040 HDR - 0002 AntiAlias - 0002 AltAntiAlias - 0002 Resolution - 0008 Aspect - 0008 DeferredLightingLight - 0002 DeferredLightingHDR - 0002 RefreshRate - 0008 SLI - 0002 Stereo - 0002 FullScreen - 0008 VSYNC - 0008 A - 0080 B - 0080 X - 0080 Y - 0080 LEFT - 0080 RIGHT - 0080 UP - 0080 DOWN - 0080 START - 0080 BACK - 0080 LT - 0080 LB - 0080 RT - 0080 RB - 0080 LSTICK_PUSH - 0080 LSTICK_VERT - 0080 LSTICK_HORZ - 0080 RSTICK_PUSH - 0080 RSTICK_VERT - 0080 RSTICK_HORZ - 0080 MouseBaseSpeed - 0001 TextureDetail - 0002 TextureMipLimite - 0002 EffectVolume - 0002 FrameRate - 0008 ShadowQuality - 0002
0001 - GAME 0002 - GRAPHICS 0004 - ??? 0008 - DISPLAY 0010 - ??? 0020 - ??? 0040 - DEVELOP 0080 - JOYPAD
This can be found at: [0xDE5340] + 0x144
This is a block of memory holding the configuration files values. The block of memory is a block of pointers to sub-objects. Think of the memory like this:
struct ConfigEntry { unsigned short Unknown; unsigned short EntryParent; // The parent of the entry. (Bitflag, enumeration.) char* PointerToName; // Points to the name of the entry. };
struct ConfigEntries { ConfigEntry Entries[]; // Unsure if the size is limited or not at this time! };
This is not all the values the config.ini can have though this is just a block of some of them!
|
|
✫Advanced Coder✫
First, I was known as Sectus. And then, well, I ended up here.
Posts: 2,811
Original Join Date: Aug 31 2009
|
Post by FluffyQuack on Jan 31, 2015 13:22:13 GMT 10
[0xD7C9C0] + 0x5114 - Current costume. This can be changed freely and game will update costume when you enter a new room. (0...3) [0xD7C9C0] + 0x5118 - Current character. This can be changed freely and game will update character when you enter a new room. (0 = Chris, 1 = Jill, 2 = Rebecca) [0xD7C9C0] + 0x5124 - Unlockables (bitflags) For inventory items, this list for REmake is still accurate for list of items in REmaster: z6.invisionfree.com/Resident_Evil_4_PC/index.php?s=e2663d87a1036b628ed6f938eccbe073&showtopic=16293
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Jan 31, 2015 15:14:54 GMT 10
Thanks, added them to the main post.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 1, 2015 10:47:30 GMT 10
Added FPS information to the main post: [0xDE4248] + 0x38 - The fps cap for the game. [0xDE4248] + 0x3C - The current in-game fps divisor. (Seems to be always 30 currently). [0xDE4248] + 0x44 - The current in-game fps.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 1, 2015 18:25:46 GMT 10
[0x0C814A0] - Controls animation speed. (The lower the value the faster you animate. This includes how fast you run.) [0xDE4248] + 0x34 - Enable / Disable rendering. (If 1, the game will stop rendering.)
[0xDE5340] + 0x20 - Enable / Disable background rendering. (When the game is alt+tabbed, should it update?)
|
|
SetMode : Enraged Mad Dog ---> SetMode : Ok
Posts: 367
|
Post by CodeMan02Fr on Feb 1, 2015 18:46:26 GMT 10
well it sound interesting but how do we use thoses ? don't they change according to bhd.exe process adress ?
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 1, 2015 19:07:46 GMT 10
well it sound interesting but how do we use thoses ? don't they change according to bhd.exe process adress ? The base address of bhd.exe should never be anything but 0x00400000. And you can use this inside of Cheat Engine or any other memory editor.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 4, 2015 18:41:39 GMT 10
biodata.bin - Location is at: C:\Program Files (x86)\Steam\userdata\<userid>\304240\remote\biodata.binThis file contains the various options / configurations of the game. Including the keyboard mapping. However this file is encrypted. The function that decryptions this file is: unsigned int __thiscall sub_69FE10(int this) { int v1; // esi@1 int v2; // edx@1 signed int v3; // edi@5 int v4; // eax@6 char *v5; // edx@6 signed int v6; // edx@7 int v7; // edi@8 signed int v8; // ebx@8 int v9; // eax@9 signed int v10; // ebp@11 unsigned int v11; // edx@12 signed int v12; // edi@13 signed int v13; // edi@15 signed int v14; // ebx@16 unsigned int result; // eax@17 int v16; // [sp+18h] [bp-14h]@5 unsigned int v17; // [sp+1Ch] [bp-10h]@5 int v18; // [sp+20h] [bp-Ch]@5 int v19; // [sp+24h] [bp-8h]@5 int v20; // [sp+28h] [bp-4h]@1
v1 = this; v2 = *(_DWORD *)(this + 276); v20 = this; if ( v2 ) { (*(void (__stdcall **)(int))(*(_DWORD *)dword_D8A19C + 48))(v2); *(_DWORD *)(v1 + 276) = 0; } if ( *(_DWORD *)(v1 + 280) ) { (*(void (__stdcall **)(_DWORD))(*(_DWORD *)dword_D8A19C + 48))(*(_DWORD *)(v1 + 280)); *(_DWORD *)(v1 + 280) = 0; } v16 = *(_DWORD *)(v1 + 8); v17 = *(_DWORD *)(v1 + 12); *(_DWORD *)(v1 + 276) = (*(int (__stdcall **)(signed int, signed int))(*(_DWORD *)dword_D8A19C + 32))(72, 16); *(_DWORD *)(v1 + 280) = (*(int (__stdcall **)(signed int, signed int))(*(_DWORD *)dword_D8A19C + 32))(4096, 16); v18 = 16 - (_DWORD)dword_D67024; v3 = 0; v19 = 20 - (_DWORD)dword_D67024; do { *(_DWORD *)(v3 * 4 + *(_DWORD *)(v1 + 276)) = dword_D67020[v3]; *(_DWORD *)(v3 * 4 + *(_DWORD *)(v1 + 276) + 4) = dword_D67024[v3]; *(_DWORD *)(v3 * 4 + 8 + *(_DWORD *)(v1 + 276)) = dword_D67028[v3]; *(_DWORD *)(v3 * 4 + 12 + *(_DWORD *)(v1 + 276)) = dword_D6702C[v3]; *(int *)((char *)dword_D67024 + v18 + v3 * 4 + *(_DWORD *)(v1 + 276)) = dword_D67030[v3]; v4 = dword_D67034[v3]; v5 = (char *)dword_D67024 + v19 + v3 * 4; v3 += 6; *(_DWORD *)&v5[*(_DWORD *)(v1 + 276)] = v4; } while ( v3 < 18 ); v6 = 0; do { v7 = v6 * 4 + 12; v8 = 64; do { *(_DWORD *)(v6 * 4 + *(_DWORD *)(v1 + 280)) = dword_D67068[v6]; *(_DWORD *)(*(_DWORD *)(v1 + 280) + v6 * 4 + 4) = dword_D6706C[v6]; v9 = dword_D67070[v6]; v6 += 4; *(int *)((char *)&dword_D6705C + 8 - (_DWORD)dword_D6706C + *(_DWORD *)(v1 + 280) + v6 * 4) = v9; *(_DWORD *)(v7 + *(_DWORD *)(v1 + 280)) = dword_D67064[v6]; v7 += 16; --v8; } while ( v8 ); } while ( v6 < 1024 ); v10 = 0; do { v10 += 4; v11 = (v8 + 4) % v17; *(_DWORD *)(*(_DWORD *)(v1 + 276) + v10 - 4) ^= *(_BYTE *)((v8 + 3) % v17 + v16) | ((*(_BYTE *)((v8 + 2) % v17 + v16) | (((*(_BYTE *)(v8 + v16) << 8) | *(_BYTE *)((v8 + 1) % v17 + v16)) << 8)) << 8); v1 = v20; v8 = v11; } while ( v10 < 72 ); v16 = 0; v17 = 0; v12 = 0; do { sub_69F830(&v16, &v17); *(_DWORD *)(v12 + *(_DWORD *)(v1 + 276)) = v16; *(_DWORD *)(v12 + *(_DWORD *)(v1 + 276) + 4) = v17; v12 += 8; } while ( v12 < 72 ); v13 = 0; do { v14 = 128; do { sub_69F830(&v16, &v17); *(_DWORD *)(v13 + *(_DWORD *)(v1 + 280)) = v16; result = v17; *(_DWORD *)(v13 + *(_DWORD *)(v1 + 280) + 4) = v17; v13 += 8; --v14; } while ( v14 ); } while ( v13 < 4096 ); return result; } Sadly this is using a mix of BLOWFISH and custom decryption methods so easy-decoding using just blowfish is not possible. I do not personally have the time to reverse all of this and write a decoder for this file, so just sharing this information for anyone interested. Another function of importance: int __thiscall sub_42F090(void *this)
{
int result; // eax@1
void *v2; // esi@1
char v3; // [sp+0h] [bp-48h]@0
int v4; // [sp+4h] [bp-44h]@2
char v5; // [sp+8h] [bp-40h]@2
result = dword_DE5210;
v2 = this;
if ( dword_DE5210 )
{
*(_DWORD *)(dword_DE5210 + 3320) = 0;
*(_DWORD *)(dword_DE5210 + 56) = 0;
*(_BYTE *)(dword_DE5210 + 3325) = 1;
v5 = 0;
v4 = 0;
if ( sub_47A510(dword_DE4248) == 1 )
sub_4024E0((int)&v4, "biohazardü@HD REMASTER", v3);
else
sub_4024E0((int)&v4, "Resident Evil", v3);
sub_837CF0(dword_DE5210, "biodata.bin");
sub_430290(v2);
sub_837D30(dword_DE5210, 1);
result = sub_837BC0(dword_DE5210, "SBmdYgEamc=#sA0)Mhs9#>/4iiXbMPxW");
}
return result;
} I believe that SBmdYgEamc=#sA0)Mhs9#>/4iiXbMPxW is the blowfish key used to decode the file.
|
|
Posts: 111
|
Post by 80t on Feb 5, 2015 8:29:27 GMT 10
I think a tool named "Horizon" package manager deals with this kind of .bin data decryption / editing. For what I can tell by searching G**gle it's XBOX 360 only... ?
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 5, 2015 15:16:43 GMT 10
Most of the function I posted above is the initialization of the blowfish routines (the P/S key tables). So the actual work is the last part. However they are using custom BLOWFISH tables, their data is not the same as standard blowfish. For example their 'P' init table is: i.imgur.com/elMVe4r.pngI am looking into dumping their P/S tables and implementing it into a working blowfish implementation. However they may have changed the shifting used and such too, so I cannot say for sure if this will work.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 5, 2015 17:46:01 GMT 10
Alright, got things working. I can decode the file properly. Some quick notes to anyone looking into this for PC: - The file is encrypted via BLOWFISH. (Standard blowfish, not using modified P/S tables, they are all default.) - The encryption key is: "SBmdYgEamc=#sA0)Mhs9#>/4iiXbMPxW" (without the quotes) - The file MUST have its endian swapped before you decrypt it. This is a must!
Some other things to note: - The file format is the same as XBOX 360's version of the game. You can fix the file and have it load with the existing XBOX360 save game editor.
I am writing an app to swap the file to XBOX and back to PC so you can use the XBOX save editor as well as load your PC saves on XBOX and vice-versa, will have it uploaded soon.
|
|
http://atom0s.com
Posts: 154
|
Post by atom0s on Feb 5, 2015 18:02:48 GMT 10
|
|