Log in

View Full Version : function epilogue..!


jackall
November 1st, 2010, 12:29
Code:
01-.text:00401040 push offset aKris_kaspersky ; "kris.kaspersky"
02.text:00401045 call sub_404C00
03.text:0040104A add esp, 8

04.text:0040104D test eax, eax
05.text:0040104F jz short loc_401065

06.text:00401051 push offset aWrongPassword ; "\nwrong password\n"
07.text:00401056 push offset unk_419570
08.text:0040105B call sub_401090

09.text:00401060 add esp, 8
10.text:00401063 jmp short loc_401077
11.text:00401065 ; ------------------------------------------------------------
12.text:00401065
13.text:00401065 loc_401065: ; CODE XREF: sub_401000+4F j
14.text:00401065 push offset aPasswordOk__ ; "\npassword OK..!\n"
15.text:0040106A push offset unk_419570
16.text:0040106F call sub_401090

17.text:00401074 add esp, 8
18.text:00401077
19.text:00401077 loc_401077: ; CODE XREF: sub_401000+63 j
20.text:00401077 xor eax, eax
21.text:00401079 mov ecx, [ebp+var_4]
22.text:0040107C xor ecx, ebp
23.text:0040107E call sub_404C88
24.text:00401083 mov esp, ebp
25.text:00401085 pop ebp
26.text:00401086 retn


line 04:
on this line , by changing (test eax, eax)--to--(xor eax, eax)
the code execution jumps over the protection and displays 'password ok' message...

Code:
.0040104d: 33c0 xor eax, eax


line06:
i would like to replace the 'wrong password' string here, with another
string say, like 'copycatcrackr! and i used hiew32 to modify the string...

Code:
.004131c0: 2e 6b 61 73-70 65 72 73-6b 79 00 00-0a 63 6f 70 .......... ◙cop
.004131d0: 79 63 61 74-20 63 72 61-63 6b 72 0a-00 00 00 00 ycat crackr◙.


the changed file(a1) loaded in ida , shows the changed string clearly:

Code:
.rdata:004131cc acopycatcrackr db 0ah ; data xref: sub_401000+51 o
.rdata:004131cc db 'copycat crackr',0ah,0

but, when the exe is run, the 'copycat cracker 'message, is missing still.!

line09:
function epilogue, collapses stack frame after the completion of the function...
by [add esp, 8]
but as this process is repeated on (line:17) , i inserted NOP on line 09..(a2).

still, more garbage..!
all 3 files are attached, for your kind perusal..

thank you..!

niaren
November 1st, 2010, 16:22
By changing
04.text:0040104D test eax, eax
to
04.text:0040104D xor eax, eax
the good boy message is always displayed. So you will never see the bad boy message. (So why change it?)

When you NOP an instruction be careful to NOP all of it. In your a1 this seems to not be the case.

Also why do you want to NOP out add esp,8 ? Unless you have made other modifications this will almost certainly lead to a crash.

WaxfordSqueers
November 1st, 2010, 19:36
Quote:
[Originally Posted by jackall;88045]
line 04:
on this line , by changing (test eax, eax)--to--(xor eax, eax)
the code execution jumps over the protection and displays 'password ok' message...


The proper way of accomplishing your goal would have been changing the jz after your test statement to jmp. That would force the program flow to always jump to the good guy part.

As niaren said, there's no need to NOP the statement you NOPed. Anytime you see the esp register used it has something to do with the stack frame and is not related directly to your app. They were saving space on the stack for the return from a function, and by NOPing it, you probably wrote all over the stack, which = crash!!

Also, when you overwrite ASCII text, be sure to overwrite it character for character. You cannot increase the number of characters, or decrease them. If your change is less than the original, you have to add characters. The '/n' character is not part of the ASCII text. You have to leave it in there.

If you alter the boundaries around the text, you change the whole program and it will crash.

Finally, some apps these days use some form of CRC protection. If you change anything in the code section, the app will crash. The does not seem to be the case with yours if you can change to an XOR command, but it's worth knowing that in case you try it with another app. In such a case, you have to find the CRC protection and bypass it, which is not that easy.

jackall
November 2nd, 2010, 01:43
Quote:
[Originally Posted by niaren;88046]By changing
04.text:0040104D test eax, eax
to
04.text:0040104D xor eax, eax

the good boy message is always displayed. So you will never see the bad boy message. (So why change it?)


thank you niaren..!

probably i botched up, to highlight clearly the area that i want to understand..!

‘goodboy’ message could be achieved, by any number of ways, and
that is easily done comparatively, at least in this instance..

but i like to learn a little more...

once execution jumps to the ‘goodboy’, the code snippet that is
meant to display ‘wrong password’ becomes superfluous.

make use of this area to announce, another message..‘copycat for the copycats’..
and then, execution PROCEEDS to ‘password ok’..!

in other words, there is no Rtn after the ‘wrong password’ display, and the Rtn
is returned only after displaying the string the ‘password ok’..with 'copycat' preceding it..

regards..

WaxfordSqueers
November 2nd, 2010, 18:19
Quote:
[Originally Posted by jackall;88054]
in other words, there is no Rtn after the ‘wrong password’ display, and the Rtn
is returned only after displaying the string the ‘password ok’..with 'copycat' preceding it..regards..
Experimenting is a good way to learn but first I suggest you figure out what each code snippet is doing.

In both the good guy and bad guy snippets, ASCII names are PUSHed. Do you understand what that means? A pointer to the character string is PUSHed onto the stack. Then a function is called at 'call sub_401090', which parses the string. When the call returns, it manipulates the stack through the esp register, by saving space for something. That why you can't NOP the esp instruction.

After the bad guy call, there is a JMP to the RET routine. If you re-direct program flow to alter that ASCII string, you will jump past the good guy routine. You would have to point the JMP to your good guy routine but then you create other problems.

You have to remember that the stack is related to the current instruction pointer. If you suddenly JMP to a new location, you have to adjust the stack, and any other related register that depends on that JMP. Otherwise, you crash. If you remove the JMP, you are messing with the stack. With nested calls, you may be messing with other parts of the program, or even from further back in the CALL structure.

It sometimes pays to trace a program from its entry point, to watch how it is set up. You will begin to realize just how intricately everything depends on everything else. Also, try your re-direction live. You will likely crash a few times but try to figure out why you crash.

BTW...turn off any disk caching if you do that. Modern systems store data before writing to disk, in a cache. If it is on, and you crash, you may wipe out your disk due to important data not having been written at the time of the crash. I have managed to recover using Chkdsk, but that is not written in stone.

jackall
November 3rd, 2010, 06:57
Quote:
[Originally Posted by WaxfordSqueers;88063] In both the good guy and bad guy snippets, ASCII names are PUSHed. Do you understand what that means? A pointer to the character string is PUSHed onto the stack. Then a function is called at 'call sub_401090', which parses the string. When the call returns, it manipulates the stack through the esp register, by saving space for something. That why you can't NOP the esp instruction.


thank you so much, for your last 2 posts...
they were truly instructive, particularly the one referring to crc protection...

in the present context:
calling code pushes the parameters to the stack, and then the processor, pushes the contents of eip, (pointer to first byte after the call), and now the callee takes charge...and a new local stack frame is created..!

now, we are in the function, which displays the string pointed to, by the pointer with a ‘copycat’ message. Then, as a rule, stack is to be cleared of the data and then the control to be returned to the caller..

09.text:00401060 add esp, 8
this ‘add’ instruction shows clearly, there are 8 bytes to be cleared from stack.
-
now, my query in fact, starts from this point on..

after displaying the string, if stack is cleared the control is returned to the caller, which would terminate the program once for all.. (is it true..?) anyway, i tried to prevent stack from being cleared, (off 8 bytes).
Code:
.text:00401060 add esp, 8

by nop-ing it, which resulted in :
Code:
.text:0040105b call sub_401090
.text:00401060 nop
.text:00401061 les ecx, [eax]

now, the execution goes over the protection, to display ‘password OK’.. after that the stack is cleared (401074) , and the control is returned to the caller..the used memory , released and program terminates, peacefully..!
Code:
.text:00401051 push offset aCopycatCrackr ; "\ncopycat crackr\n"
.text:00401056 push offset unk_419570
.text:0040105B call sub_401090

.text:00401060 nop
.text:00401061 les ecx, [eax]
.text:00401063 jmp short loc_401077
.text:00401065 ; -------------------------------------------------------------
.text:00401065
.text:00401065 loc_401065: ; CODE XREF: sub_401000+4F j
.text:00401065 push offset aPasswordOk__ ; "\npassword OK..!\n"
.text:0040106A push offset unk_419570
.text:0040106F call sub_401090
.text:00401074 add esp, 8
.text:00401077
.text:00401077 loc_401077: ; CODE XREF: sub_401000+63 j
.text:00401077 xor eax, eax
.text:00401079 mov ecx, [ebp+var_4]
.text:0040107C xor ecx, ebp
.text:0040107E call sub_404C88
.text:00401083 mov esp, ebp
.text:00401085 pop ebp
.text:00401086 retn

but, i failed to get the intended string display:
i find 'password ok'..!, but fails to get copycat crackr..!

and what is this .text:00401061 les ecx, [eax]..?
so i was wondering, where my shallow reasoning had gone, exceptionally low..!
.

Maximus
November 3rd, 2010, 07:15
IDA Pro->General->Number of Opcode Bytes->set 6 or 8.

Then redo your patching work from start and watch why LES instruction come out...

jackall
November 3rd, 2010, 11:26
Quote:
[Originally Posted by Maximus;88091]IDA Pro->General->Number of Opcode Bytes->set 6 or 8.
Then redo your patching work from start and watch why LES instruction come out...

Code:
01|.text:0040104D test eax, eax
02|.text:0040104F jz short loc_401065

03|.text:00401051 push offset aWrongPassword ; "\nwrong password\n"
04|.text:00401056 push offset unk_419570
05|.text:0040105B call sub_401090
06|.text:00401060 add esp, 8
07|.text:00401063 jmp short loc_401077
08|.text:00401065 ; -----------------------------------------------------------
09|.text:00401065
10|.text:00401065 loc_401065: ; CODE XREF: sub_401000+4F j
11|.text:00401065 push offset aPasswordOk__ ; "\npassword OK..!\n"
12|.text:0040106A push offset unk_419570
13|.text:0040106F call sub_401090
14|.text:00401074 add esp, 8
15|.text:00401077
16|.text:00401077 loc_401077: ; CODE XREF: sub_401000+63 j
17|.text:00401077 xor eax, eax
18|.text:00401079 mov ecx, [ebp+var_4]
19|.text:0040107C xor ecx, ebp
20|.text:0040107E call sub_404C88
21|.text:00401083 mov esp, ebp
22|.text:00401085 pop ebp
23|.text:00401086 retn

: 401051
the string ‘wrong password’ could be changed to as: ‘bigg challenge’.
how to prevent this function from returning, after displaying the string.?
and continue to the code ‘password OK’..?

:401063
how about nop-ing the jmp at :401063
but error reports, an error at 00001067..
where is the address 00001067..?

:401074
may be the problem lies here:
twice the stack is cleared by (add esp, 8), at 401060 and at 401074..
so, i nop the one, at 401074..

rejected again..
it does not save the situation...
same error reported..!

please show a little more generosity to this simple mortal,
and kindly explain the error, and how to get over it..!

regards..
.

Maximus
November 3rd, 2010, 11:30
you havent done what i suggested you to do.
If you did, you would have seen on left after the address the BYTES of the asm opcodes, so you'd have seen where your NOP were landing - only one one byte of the instruction thus transforming the remaining byutes in 'something else'.

jackall
November 3rd, 2010, 11:54
Quote:
[Originally Posted by Maximus;88094]you havent done what i suggested you to do.
If you did, you would have seen on left after the address the BYTES of the asm opcodes, so you'd have seen where your NOP were landing - only one one byte of the instruction thus transforming the remaining byutes in 'something else'.


my apologies..!

i did change it to 8, but did not realize the purpose or effect of that entry hence i was not aware of, what to look for, or where to look, for that change.

and when i loaded the file again, probable it, returned to it default value 0.
now that i have seen the change and of course, would try to find out more..

meanwhile , it’s a pleasure to learn from such enthusiastic, conversant people
and it makes the learning a delightful experience.

thank you..
regards..
.

WaxfordSqueers
November 4th, 2010, 00:55
Quote:
[Originally Posted by jackall;88088]after displaying the string, if stack is cleared the control is returned to the caller, which would terminate the program once for all.. (is it true..?) anyway, i tried to prevent stack from being cleared, (off 8 bytes).
Code:
.text:00401060 add esp, 8

by nop-ing it, which resulted in :
Code:
.text:0040105b call sub_401090
.text:00401060 nop
.text:00401061 les ecx, [eax]

now, the execution goes over the protection, to display ‘password OK’.. after that the stack is cleared (401074) , and the control is returned to the caller..the used memory , released and program terminates, peacefully..!
the program terminated more by good luck than anything.

Look at your code after you NOPed the ADD statement. It now has a LES instruction which was not in the original code.

Maximus was trying to tell you to set the number of code bytes in IDA so they will appear in your display between the address and instructions. You can't use one NOP only. You must insert 90 (NOP) in each byte of the instruction you want to delete. If you can't see the number of code bytes, because they are turned off in IDA, you can't tell how many bytes to NOP.

You have NOPed the first code byte for the ADD instruction and left the rest. An instruction like ADD will have at least 2 code bytes and you have only NOPed one byte. The processor now interprets the rest of the bytes as a LES instruction. There should be a JMP instruction there.

Read the post from maximus again and turn on the code bytes in IDA, then you'll see the problem.

jackall
November 4th, 2010, 10:39
Quote:
[Originally Posted by WaxfordSqueers;88108] You can't use one NOP only. You must insert 90 (NOP) in each byte of the instruction you want to delete. If you can't see the number of code bytes, because they are turned off in IDA, you can't tell how many bytes to NOP.

You have NOPed the first code byte for the ADD instruction and left the rest. An instruction like ADD will have at least 2 code bytes and you have only NOPed one byte. The processor now interprets the rest of the bytes as a LES instruction. There should be a JMP instruction there.


i must acknowledge that your clarification in the context was extremely practical and positively useful. you have clearly explained not only, how and how long to nop, but why the unwanted ‘les’, makes it’s unasked for appearance, at the mainly unwelcome time..!
Code:

|.text:00401051 push offset aCopycatCrackr ; "\ncopycat crackr\n"
|.text:00401056 push offset unk_419570
|.text:0040105B call sub_401090

|.text:00401060 nop
|.text:00401061 nop
|.text:00401062 nop
|.text:00401063 nop
|.text:00401064 nop
|.text:00401065
|.text:00401065 loc_401065: ; CODE XREF: sub_401000+4F j
|.text:00401065 push offset aPasswordOk__ ; "\npassword OK..!\n"
|.text:0040106A push offset unk_419570
|.text:0040106F call sub_401090
.. .. .. .. .. .. .. ..
|.text:00401086 retn
|.text:00401086 sub_401000 endp
thank you so much ..i got the result i was hoping for, and the going on, was truly very informative..
regards..!
.

WaxfordSqueers
November 4th, 2010, 18:44
Quote:
[Originally Posted by jackall;88109]..i got the result i was hoping for, and the going on, was truly very informative..regards..!.


That's good, but remember what Maximus said, change the setting in IDA to:

IDA Pro->General->Number of Opcode Bytes->set 6 or 8.

If you keep that setting turned on, it is very helpful, especially when you post code in RCE. While I am working with code, in Softice or IDA, I keep an assembler language book nearby so I can look up opcode bytes. Each instruction has its own opcode and different instructions have different ways of handling the parameters that accompany them.

When you have to modify program code at the assembler level, it is always done with opcode byte changes. Learning how that works is invaluable, and by keeping opcode bytes turned on in IDA, it helps you learn which opcode goes with each instruction.