Another ReverseMe that the whole family will love!
by SantMat
Tutorial by Lucifer48 [Immortal Descendants]
(July 1st, 2000)
Let's begin by the easiest part, patching the nag; this is the beginning of the reverseme:
XXXX:00401000 6A00 PUSH 00
XXXX:00401002 E859010000 CALL KERNEL32!GetModuleHandleA
XXXX:00401007 A39C304000 MOV [0040309C], EAX
XXXX:0040100C 6A00 PUSH 00 ;no value (lparam)
XXXX:0040100E 6842104000 PUSH 00401042 ;offset DlgProc
XXXX:00401013 6A00 PUSH 00 ;no parent hwnd
XXXX:00401015 6800304000 PUSH 00403000 ;MEMO
XXXX:0040101A FF359C304000 PUSH DWORD PTR [0040309C] ;hInstance
XXXX:00401020 E81D010000 CALL USER32!DialogBoxParamA
Remark: The following calls (LoadLibrary, FreeLibrary, GetProcAdress) will help us !
Just two small values to patch:
XXXX:0040100C 6A00 PUSH 00 ;no value (lparam)
XXXX:0040100E 68BF104000 PUSH 004010BF ;right DlgProc
XXXX:00401013 6A00 PUSH 00 ;no parent hwnd
XXXX:00401015 6805304000 PUSH 00403005 ;GAME
XXXX:0040101A FF359C304000 PUSH DWORD PTR [0040309C] ;hInstance
XXXX:00401020 E81D010000 CALL USER32!DialogBoxParamA
Two bytes to change, not so hard !
Let's now activate the two buttons. This is the control-ID i need:
Name: GAME, # of Controls=008, Caption:"Two-Player Number Battler!", ClassName:""
001 - ControlID:FFFF, Control Class:"STATIC" Control Text:"Player 1, use the mouse or letter "z" ..."
002 - ControlID:03EF, Control Class:"EDIT" Control Text:"" <- on the right
003 - ControlID:03F0, Control Class:"EDIT" Control Text:"" <- on the left
....
For the game itself, this the way i will organize things:
I need 5 bytes:
- Player 1's score
- player 2's score
- Status : 4 différent cases
- 0 : nobody has played yet : the two editbox are empty
- 1 : player 1 is playing (but player 2 has not still played)
- 2 : player 2 is playing (but player 1 has not still played)
- 3 : player 1 is playing (and player 2 has already played) or player 2 is playing (and player 1 has already played)
(for this last case, we update scores et clear the two editbox ; and possibly end of the game)
- Valeur player 1
- Valeur player 2
An interesting piece of WM_COMMAND:
XXXX:004010DF 817D0C11010000 CMP DWORD PTR [EBP+0C], 00000111;WM_COMMAND
XXXX:004010E6 7547 JNZ 0040112F
XXXX:004010E8 8B4510 MOV EAX, [EBP+10] ;wparam
XXXX:004010EB 663DED03 CMP AX, 03ED ;button "Player 1"
XXXX:004010EF 751B JNZ 0040110C
XXXX:004010F1 C1E810 SHR EAX, 10
XXXX:004010F4 660BC0 OR AX, AX ;not really useful... (BN_CLICKED)
XXXX:004010F7 7513 JNZ 0040110C ;.if ...
XXXX:004010F9 6A00 PUSH 00 ;MB_OK
XXXX:004010FB 680A304000 PUSH 0040300A ;"Number Game"
XXXX:00401100 6816304000 PUSH 00403016 ;"This is the part you need to change ..."
XXXX:00401105 6A00 PUSH 00 ;no hwnd (and dword ptr [ebp+4] ?)
XXXX:00401107 E842000000 CALL USER32!MessageBoxA
As the cave at the end of .code is not enough (for me!), i will add a new section.
XXXX:004010F9 800D5761400001 OR BYTE PTR [00406157], 01
XXXX:00401100 E8FB4E0000 CALL 00406000
XXXX:00401105 EB31 JMP 00401138
I do the same for player 2:
XXXX:0040110C 663DEE03 CMP AX, 03EE ;button "Player 2"
XXXX:00401110 7526 JNZ 00401138
XXXX:00401112 C1E810 SHR EAX, 10
XXXX:00401115 660BC0 OR AX, AX
XXXX:00401118 7513 JNZ 0040112D
XXXX:0040111A 6A00 PUSH 00
XXXX:0040111C 680A304000 PUSH 0040300A ;"Number Game"
XXXX:00401121 6856304000 PUSH 00403056 ;"This is the other part you need to change ..."
XXXX:00401126 6A00 PUSH 00 ;no hwnd
XXXX:00401128 E821000000 CALL USER32!MessageBoxA
XXXX:0040112D EB09 JMP 00401138
i replace by:
XXXX:0040111A 800D5761400002 OR BYTE PTR [00406157], 02
XXXX:00401121 E8DA4E0000 CALL 00406000
XXXX:00401126 EB10 JMP 00401138
Let's look after the code to add in 0046000. So i add a new section ; i slightly change the PE (header), like that:
Name V.Size V.Offset R.Size R.Offset Characteristics
-----------------------------------------------------------------
.lucy 00000400 00006000 00000400 00001E00 C0000040
Don't forget to add 1000h to the Size of image.
Once the PE modified, just stay to physically add 1024 bytes to the file, for this i use
Hex Workshop. We have now more free space to succeed :)
I need to process the WM_INITDIALOG message for making few initialization (mainly for finding API addresses i need).
Fortunately, SantMat already put the jump :)
XXXX:004010BF 55 PUSH EBP ;beginning of the DlgProc
XXXX:004010C0 8BEC MOV EBP, ESP
XXXX:004010C2 817D0C10010000 CMP DWORD PTR [EBP+0C], 000110 ;.if uMsg==WM_INITDIALOG
XXXX:004010C9 7502 JNZ 004010CD
XXXX:004010CB EB6B JMP 00401138 ;we will change this jump
XXXX:004010CD 837D0C10 CMP DWORD PTR [EBP+0C], 10 ;.if uMsg==WM_CLOSE
It will jump just above this DlgProc, there is the first DlgProc, which is no more used.
XXXX:004010CB EB98 JMP 00401065
This is the init code:
XXXX:00401065 E8F1500000 CALL 0040615B ;find my API addresses
XXXX:0040106A 6825624000 PUSH 00406225 ;"Player 1 (&z)"
XXXX:0040106F 68ED030000 PUSH 000003ED ;left button
XXXX:00401074 FF7508 PUSH DWORD PTR [EBP+08] ;handle of the dialog box
XXXX:00401077 FF1511624000 CALL [00406209] ;USER32!SetDlgItemTextA
XXXX:0040107D 68ED030000 PUSH 000003ED
XXXX:00401082 FF7508 PUSH DWORD PTR [EBP+08]
XXXX:00401085 FF1511624000 CALL [00406211] ;USER32!GetDlgItem
XXXX:0040108B A31D624000 MOV [0040621D], EAX ;save the (left) button handle
XXXX:00401090 6833624000 PUSH 00406233 ;"Player 2 (&m)"
XXXX:00401095 68EE030000 PUSH 000003EE ;right button
XXXX:0040109A FF7508 PUSH DWORD PTR [EBP+08]
XXXX:0040109D FF1509624000 CALL [00406209] ;USER32!SetDlgItemTextA
XXXX:004010A3 68EE030000 PUSH 000003EE
XXXX:004010A8 FF7508 PUSH DWORD PTR [EBP+08]
XXXX:004010AB FF1511624000 CALL [00406211] ;USER32!GetDlgItem
XXXX:004010B1 A321624000 MOV [00406221], EAX ;save the (right) button handle
XXXX:004010B6 B801000000 MOV EAX, 00000001
XXXX:004010BB C9 LEAVE
XXXX:004010BC C21000 RET 0010
For the code which is located in the .lucy section, i won't paste it here. Just have a glance
here.
Last Remark:
- My number generator is lame !!! (it is located at the end of the section, you can change it easily).
- The only (other) way i have found to create shortcuts, that's using SetWindowsHookEx; endeed, the dialog
boxes created with DialogBoxParam don't receive WM_CHAR, WM_KEYUP and WM_KEYDOWN. In addition, there is no message
loop (it is internal), it is not possible to use accelerator (CreateAcceleratorTable, ...).
- Displaying scores would have been great !
- The game continue until somebody reaches 5 points and not 50.
- etc etc.
Greetings: All the #immortaldescendants channel. And SantMat, congratulations for your bady !
(c) Lucifer48. All rights reserved & reversed