PDA

View Full Version : [Help!!] Disassembled code..


gaitmia
June 6th, 2007, 17:34
Hi, i disassembled an app and found the piece of code below.
The address: 00684C20 is the begin of a function and it's called from 004D50D2, no problem here!
Code:

00684C1F 9>NOP
00684C20 /$ 8>MOV ECX,DWORD PTR DS:[7D60288] ; << It has 1 "Local call from" >>
00684C26 |. 8>TEST ECX,ECX
00684C28 |. 7>JNZ SHORT main-U-1.00684C2D
00684C2A |. 3>XOR AL,AL
00684C2C |. C>RETN
00684C2D |> 8>MOV EAX,DWORD PTR SS:[ESP+4]
00684C31 |. 5>PUSH EAX
00684C32 |. E>CALL main-U-1.00686E50
00684C37 \. C>RETN
00684C38 9>NOP
00684C39 9>NOP
00684C3A 9>NOP
00684C3B 9>NOP


Below there is another similar function at address: 00684C40.

Code:

00684C3C 9>NOP
00684C3D 9>NOP
00684C3E 9>NOP
00684C3F 9>NOP
00684C40 . 8>MOV ECX,DWORD PTR DS:[7D60288] ; << it doesn't have any "Local calls from"!! >>
00684C46 . 8>TEST ECX,ECX
00684C48 . 7>JNZ SHORT main-U-1.00684C4D
00684C4A . 3>XOR AL,AL
00684C4C . C>RETN
00684C4D > 8>MOV EAX,DWORD PTR SS:[ESP+4]
00684C51 . 5>PUSH EAX
00684C52 . E>CALL main-U-1.00686F20
00684C57 . C>RETN
00684C58 9>NOP
00684C59 9>NOP
00684C5A 9>NOP
00684C5B 9>NOP
00684C5C 9>NOP
00684C5D 9>NOP
00684C5E 9>NOP
00684C5F 9>NOP

When i select the 00684C40 address, ollydbg doesn't show me any "Local Call From"! WTF???

I already tried to search for the command "PUSH 00684C40", also for the constant=684c40 and also
selecting that line and clicking on "Find References to->Selected command", but none of
those actions doesn't find anything related to that address!!!

Can anyone say me anothers ways to find references to this function, please???

Thanks!

naides
June 6th, 2007, 18:30
Olly and (IDA for that matter) can only locate references that are explicit in the disassembly:

CALL 00684C40

JMP 00684C40.

The code, if it is called at all, may be referenced by something like

MOV eax, 00684C3F

INC eax (Now eax == 00684C40)

CALL eax or

JMP eax

for instance. (The point is that the address is calculated somehow at run time, this is just an oversimplified example).

It also looks fishy that you have two code snippets, essentially a carbon copy from each other nearby in memory.

Anyway: One long shot at finding the answer to your question is to place a breakpoint at 00684C40. the run your program checking different menus and options and hope it will eventually run through that code and break.

Then start looking at the call stack, the top of the stack and the registers, which may reveal where the code was called or jumped from. a cryptic Jump EAX like instruction is perhaps less traceable. Also, learn to use the run trace option of Olly, which will save a trace history of the instructions immediately before your code snippet is ran/called and take it from there. . .

gaitmia
June 6th, 2007, 19:27
I can't break on that address because i know it'll never be called by the program when it's executing unpacked in a debugger.
So, i need to discard the tracing method and want to find anothers ways using only the disassembly approaches. I tried to look for threadprocs too but no success.
More ideas, please!!

Kayaker
June 6th, 2007, 21:05
You say the first proc is called from 004D50D2. By what method is it called and how were you able to find an xref for it?

Assuming (knowing one should never ASSuME) that the 2nd proc is called in the same manner, isn't it possible that this is simply orphaned code that was compiled but not used, if you can't find an xref the same way you did for the 1st?

gaitmia
June 6th, 2007, 23:21
Quote:
[Originally Posted by Kayaker;66215]You say the first proc is called from 004D50D2. By what method is it called ...and how were you able to find an xref for it?

The first proc is called using a normal CALL instruction (look below). (I'm sorry, but i didn't understand the question about xret..)
Code:

..
004D50CB |. 8>MOV ECX,DWORD PTR SS:[EBP+8]
004D50CE |. 8>MOV EDX,DWORD PTR DS:[ECX+4]
004D50D1 |. 5>PUSH EDX
004D50D2 |. E>CALL 00684C20 ; << Here it calls the 1st proc >>
004D50D7 |. 8>ADD ESP,4
004D50DA |> 8>MOV ECX,DWORD PTR SS:[EBP-C]
004D50DD |. B>MOV EAX,1
004D50E2 |. 6>MOV DWORD PTR FS:[0],ECX
004D50E9 |. 8>MOV ESP,EBP
004D50EB |. 5>POP EBP
004D50EC \. C>RETN
..


Quote:
[Originally Posted by Kayaker;66215]
Assuming (knowing one should never ASSuME) that the 2nd proc is called in the same manner, isn't it possible that this is simply orphaned code that was compiled but not used, if you can't find an xref the same way you did for the 1st?

I don't understand what u mean with xret. I'm nb on this area and don't know some expressions.
What i know is that the 2nd proc is executed by the original exe, because it sends important data to a remote server. Look again the 2nd proc and i explain this better, below:

Code:

..
00684C3F 9>NOP
00684C40 . 8>MOV ECX,DWORD PTR DS:[7D60288] ; << it doesn't have any "Local calls from"!! >>
00684C46 . 8>TEST ECX,ECX
00684C48 . 7>JNZ SHORT main-U-1.00684C4D
00684C4A . 3>XOR AL,AL
00684C4C . C>RETN
00684C4D > 8>MOV EAX,DWORD PTR SS:[ESP+4]
00684C51 . 5>PUSH EAX
00684C52 . E>CALL 00686F20 ; Important call!
00684C57 . C>RETN
00684C58 9>NOP
...


The proc 00686F20 that is called at address: 0684C52 is an important routine that is necessary to run the application properly. So, i'm 100% sure that this call is executed by the original exe! Is this info useful for u?

Please, i really need some help with this!

Kayaker
June 7th, 2007, 01:46
Sorry, XREF is short form for cross-reference, if you were to use IDA you would see that jump and call destinations are marked as XREF's.

So the first proc is called as
004D50D1 PUSH EDX
004D50D2 CALL 00684C20

And presumably you (and Olly) can't find any reference to the 2nd proc being called in a similar manner, as in
PUSH EDX
CALL 00684C40

So if it's not a straight Call, then it could be any combination of instructions as naides mentioned, push/ret, jmp eax, etc., and the address 00684C40 could easily be calculated runtime. Hard to find from a disassembly in that case.
Perhaps the calling function isn't even decrypted yet at the point you're looking at it, or is hidden in self modifying code (SMC).

Maybe you could look for a similar pattern in how the stack parameter is set up, even if you can't find a direct reference to how 00684C40 is reached, even though that's kind of grasping at straws.

It looks like
004D50CB MOV ECX,DWORD PTR SS:[EBP+8]
004D50CE MOV EDX,DWORD PTR DS:[ECX+4]
004D50D1 PUSH EDX
is the stack parameter being set up for use in
00684C2D MOV EAX,DWORD PTR SS:[ESP+4]

Maybe the 2nd proc also uses
MOV <r1>, DWORD PTR SS:[EBP+8]
MOV <r2>, DWORD PTR DS:[ <r1> +4]
PUSH <r2>
to set up the stack for the instruction
00684C4D MOV EAX,DWORD PTR SS:[ESP+4]

blabberer
June 7th, 2007, 09:12
00684C20 /$ 8>MOV ECX,DWORD PTR DS:[7D60288] ; << It has 1 "Local call from" >>

00684C40 . 8>MOV ECX,DWORD PTR DS:[7D60288] ; << it doesn't have any "Local calls

there is a very good visual clue there
and ollydbg has shown why it is behaving the way it is behaving

you are not understanding the clue and thats your problem

684c20 is called directly (first executable line of a function/ procedure)
684c40 is part of some crap function ( may be, will be, might be executed after a million instructions if at all executed )

see the MONEY Symbol MONEY matters a lot dont you think ?


if you want to find a referance to it if it exists select the second line and press ctrl+r or right click find referances to selected whatever

gaitmia
June 7th, 2007, 15:57
Quote:
[Originally Posted by Kayaker;66227]Sorry, XREF is short form for cross-reference, if you were to use IDA you would see that jump and call destinations are marked as XREF's.

So the first proc is called as
004D50D1 PUSH EDX
004D50D2 CALL 00684C20

And presumably you (and Olly) can't find any reference to the 2nd proc being called in a similar manner, as in
PUSH EDX
CALL 00684C40

So if it's not a straight Call, then it could be any combination of instructions as naides mentioned, push/ret, jmp eax, etc., and the address 00684C40 could easily be calculated runtime. Hard to find from a disassembly in that case.
Perhaps the calling function isn't even decrypted yet at the point you're looking at it, or is hidden in self modifying code (SMC).

Maybe you could look for a similar pattern in how the stack parameter is set up, even if you can't find a direct reference to how 00684C40 is reached, even though that's kind of grasping at straws.

It looks like
004D50CB MOV ECX,DWORD PTR SS:[EBP+8]
004D50CE MOV EDX,DWORD PTR DS:[ECX+4]
004D50D1 PUSH EDX
is the stack parameter being set up for use in
00684C2D MOV EAX,DWORD PTR SS:[ESP+4]

Maybe the 2nd proc also uses
MOV <r1>, DWORD PTR SS:[EBP+8]
MOV <r2>, DWORD PTR DS:[ <r1> +4]
PUSH <r2>
to set up the stack for the instruction
00684C4D MOV EAX,DWORD PTR SS:[ESP+4]


Thanks for ur suggestion. it was a good idea, i'm trying to search for some similar commands, to see if that is some indirect call instruction near of them..

Maybe u know can answer me if there is a possibility that this 2nd proc is being called by a remote thread created by another process? I was thinking on this because there is really another process that controls this app, when it's in the original format ...

Quote:
[Originally Posted by blabberer;66239]
there is a very good visual clue there
and ollydbg has shown why it is behaving the way it is behaving

you are not understanding the clue and thats your problem

684c20 is called directly (first executable line of a function/ procedure)
684c40 is part of some crap function ( may be, will be, might be executed after a million instructions if at all executed )

see the MONEY Symbol MONEY matters a lot dont you think ?


if you want to find a referance to it if it exists select the second line and press ctrl+r or right click find referances to selected whatever

I understand now that this 2nd proc can be called by any part of the executable and I already said ctrl+r didn't help me because it doesn't show any thing related to that proc!

If existed something that lists all addresses that do "indirect call", it would help a lot. The exe is 5MB long and it can contain more than millions of indirect calls for me to search for.

Thanks for the replies.

xenakis
June 7th, 2007, 19:16
Quote:
[Originally Posted by gaitmia;66213]I can't break on that address because i know it'll never be called by the program when it's executing unpacked in a debugger.

Just to be thorough, how do you know that it will never be called when being debugged? And if you are indeed certain that the app can detect debugging, perhaps fixing the debugger check/hiding olly might be a faster way of solving your troubles.
This could even be a dummy procedure, placed there to throw curious minds off the path.

naides
June 7th, 2007, 21:04
Quote:
[Originally Posted by gaitmia;66245]
If existed something that lists all addresses that do "indirect call", it would help a lot.

Lists of indirect calling are very useless I am afraid.

call R32 (call any 32 bit register) are waaay to common

Call DWORD PTR [ebp+xxxxxxxx]

so that ebp and xxxxxxxx can be anything

Call [Jmp [pointer or register or constant]

push R32 (containing your code address)
ret;

Particularly if the protector is coding in ASM and has low level knowledge of the CPU dynamics you are on for a lot of guessing, trivial pursuits. . . and mirages. . .

As you yourself mention, another thread, or another process may gain the value of a pointer to your "unreferenced" code using GetProcAddress, read from global variables, any other way you name it, plus other very convoluted transactions among processes taking place in code that does not exist in your memory space or in your disassembly, so you may never catch it.

Bottom line,

Look for a lateral solution to your problem.

Google 'lateral thinking' 'lateral logic' 'lateral problem' lateral solution' and you will find new avenues to attack your current impasse

LLXX
June 10th, 2007, 01:12
Quote:
[Originally Posted by naides;66251]Particularly if the protector is coding in ASM and has low level knowledge of the CPU dynamics you are on for a lot of guessing, trivial pursuits. . . and mirages. . .
Based on the code fragments I've seen so far, this appears to be a standard compiled app written in C++. Both of the functions are of this form:
Code:
char f_00684C40(int arg1) {
if(g_07D60288) {
f_00686F20(arg1);
} else return 0;
}

Code:
char f_00684C20(int arg1) {
if(g_07D60288) {
f_00686E50(arg1);
} else return 0;
}
I suggest you disassemble the functions at 00686F20 and E50 for further examination.

Code:
004D50CB |. 8>MOV ECX,DWORD PTR SS:[EBP+8]
004D50CE |. 8>MOV EDX,DWORD PTR DS:[ECX+4]
004D50D1 |. 5>PUSH EDX
004D50D2 |. E>CALL 00684C20 ; << Here it calls the 1st proc >>
004D50D7 |. 8>ADD ESP,4
004D50DA |> 8>MOV ECX,DWORD PTR SS:[EBP-C]
004D50DD |. B>MOV EAX,1
004D50E2 |. 6>MOV DWORD PTR FS:[0],ECX
004D50E9 |. 8>MOV ESP,EBP
004D50EB |. 5>POP EBP
004D50EC \. C>RETN
Looks like a member function call. This is evident from the use of "thiscall" convention, where the object structure pointer is passed in ECX.

No Asm programmer would write code like this, this has to be a compiler output.

You may want to read http://www.openrce.org/articles/full_view/23 for more information on understanding C++ compiler generated code.

naides
June 10th, 2007, 05:24
Thank you for the explanation Lithana.
I mentioned an ASM coder as a hypothetical, extreme example on how a call to a particular code snippet can be impossible to trace. Sorry if I falsely implied that this example was coded directly in ASM.

On that vein:
the two carbon copies of code snippets are padded with nops and are located exactly 0x20 bytes apart in memory, which a is curiously round and paragraph aligned number.
The mechanism that selects and call the function 00684C20 (to which you do have a explicit reference) probably calls 00684C40 (00684C20 + 20) very near by. Is there anything similar located at 00684C60 ??

LLXX
June 10th, 2007, 06:26
Quote:
[Originally Posted by naides;66295]the two carbon copies of code snippets are padded with nops and are located exactly 0x20 bytes apart in memory, which a is curiously round and paragraph aligned number.
This is a default "fastest code" optimiser alignment. Watch:
Code:
main() {
func1();
func2();
}

func1() {
return 2;
}

func2() {
return 1;
}

Code:
cl /O2 testalign.c

Code:
00401000 call 000401010
00401005 jmp .000401020
0040100A nop
0040100B nop
0040100C nop
0040100D nop
0040100E nop
0040100F nop
00401010 mov eax,000000002
00401015 retn
00401016 nop
00401017 nop
00401018 nop
00401019 nop
0040101A nop
0040101B nop
0040101C nop
0040101D nop
0040101E nop
0040101F nop
00401020 mov eax,000000001
00401025 retn

Code:
int main() {
f_00401010();
f_00401020(); /* all.func.flowtransfer:TailSimCall */
}

int f_00401010() {
return 2;
}

int f_00401020() {
return 1;
}

blabberer
June 10th, 2007, 06:57
litana
thats a nice explanation and disassembly
but coming from ollydbg angle ollydbg will recognize
both the calls

it wont be orphan like he states without any referance

can you make that magic too ?

preferably a statistically unresolvable call eax kind of call that wouldn't be able to catch your

func() ?

no direct calls no direct jumps

LLXX
June 10th, 2007, 18:54
That was in response to naides' question about the NOPs


Read the link two posts previous for the answer to your question.

http://msdn.microsoft.com/msdnmag/issues/0300/c/ is also relevant.