| View previous topic :: View next topic |
| Author |
Message |
tombana Master Cheater
Reputation: 2
Joined: 14 Jun 2007 Posts: 456 Location: The Netherlands
|
Posted: Sat Jan 10, 2009 2:21 am Post subject: |
|
|
| dnsi0 wrote: | | tombana wrote: | | And if you hook at the return (so if you replaced the RETN with a JMP) then it's also [esp]. |
I don't think that works... You still have to pop all those values from the stack. |
Well, like BanMe showed, if you hook at the RET (so áfter the 'leave') then the program should have already restored the stack otherwise the return wouldn't be working properly. One problem might be that the function has multiple returns, so you would have to hook them all.
| BanMe wrote: | | Code: |
__declspec(naked)void Hk_OpenThreadToken()
{
DWORD RetAddress;
__asm
{
mov RetAddress,[esp]
mov edi,edi
push ebp
mov ebp,esp
jmp OpenThreadToken+5
}
} |
|
How would the compiler allocate stack space for RetAddress in this case? (I mean when the function has __declspec(naked)) Since you did [esp] I'm assuming the stack would still be the same as before the allocation of RetAddress. |
|
| Back to top |
|
 |
rapion124 Grandmaster Cheater Supreme
Reputation: 0
Joined: 25 Mar 2007 Posts: 1095
|
Posted: Sat Jan 10, 2009 8:35 am Post subject: |
|
|
I don't use a variable in the stack. I just push the [esp] value and then call another function with the __STDCALL calling convention, which does something with the return address and restores the stack.
I do this:
| Code: |
API_CODE:
//Hook here ([esp])
mov edi, edi
push ebp
mov ebp, esp
//Hook here ([esp+4])
...
pop ...
pop ...
leave
//Hook here ([esp])
ret x
Hook:
push [esp] //or [esp+4]
call PrintReturnAddress //__STDCALL
ret x //or trampoline back
| [/code] |
|
| Back to top |
|
 |
BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Sat Jan 10, 2009 11:46 am Post subject: |
|
|
hmm i didnt think of it that way tombana.. i was quite tired when i wrote the example out.. removing the __declspec(naked) would prolly be the best course of action..
alternativly a Global or the smart use of push/pop
another form of preamble is the SEH installation code which usually looks as such
| Code: |
push 0xdeadc0de//xyz code
call InstallSeh
push ebp
mov ebp,esp
xyzcode
pop ebp
UninstallSeh
ret
|
now this form of preamble is usually used in the "W" and "Ex" functions
so hooking here is pretty simple just rewrite the Push.. (no examples)..
heres a example of using push/pop to get what we need with the naked attribute using thr same example from above hooking the preamble
| Code: |
__declspec(naked)void Hk_OpenThreadToken()
{
__asm
{
pop eax//gets esp
push eax//restores it
mov edi,edi
push ebp
mov ebp,esp
jmp OpenThreadToken+5
}
}
|
|
|
| Back to top |
|
 |
dnsi0 I post too much
Reputation: 0
Joined: 04 Jan 2007 Posts: 2674
|
Posted: Sat Jan 10, 2009 2:13 pm Post subject: |
|
|
these all have the header of
push ebp and mov ebp,esp
And why use mov edi,edi? its the same as nop. don't need it.
And also the code that Im trying to hook isn't like that.
It does not have the usual push ebp and mov ebp,esp.
It starts off with a mov eax,[value]
and ends with
leave
ret |
|
| Back to top |
|
 |
sponge I'm a spammer
Reputation: 1
Joined: 07 Nov 2006 Posts: 6009
|
Posted: Sat Jan 10, 2009 3:35 pm Post subject: |
|
|
| dnsi0 wrote: | these all have the header of
push ebp and mov ebp,esp
And why use mov edi,edi? its the same as nop. don't need it.
And also the code that Im trying to hook isn't like that.
It does not have the usual push ebp and mov ebp,esp.
It starts off with a mov eax,[value]
and ends with
leave
ret |
There is an ENTER instruction or push ebp, mov ebp, exp somewhere. The proof is in the LEAVE instruction. _________________
|
|
| Back to top |
|
 |
BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Sat Jan 10, 2009 4:55 pm Post subject: |
|
|
mov edi,edi is a component of hotpatching research it eclicz wrote a nice paper on it.. ;p
and if ur function has a leave that means there is a enter somewhere probably a conditional jump that jumps to ur supposed start
regard BanMe |
|
| Back to top |
|
 |
tombana Master Cheater
Reputation: 2
Joined: 14 Jun 2007 Posts: 456 Location: The Netherlands
|
Posted: Sun Jan 11, 2009 6:52 am Post subject: |
|
|
| If there is a 'leave' I don't think there needs to be an 'enter'. In masm, just create a simple function with parameters and local variables and compile that. In olly you'll see that masm will generate a push ebp; mov ebp, esp; and at the end of the function it will do leave; retn;. The leave instruction will just do mov esp, ebp; pop ebp;. |
|
| Back to top |
|
 |
dnsi0 I post too much
Reputation: 0
Joined: 04 Jan 2007 Posts: 2674
|
Posted: Sun Jan 11, 2009 8:52 am Post subject: |
|
|
Thats not right...
I looked through the code and did not find it anywhere and don't tell me to look above cause above there is only a leave and ret
SO it looks like this:
leave
ret
mov eax.[some addy I forgot]
*rest of the code w/o and push ebp and mov ebp,esp
leave
ret.
I thought I got the wrong function so I put a bp on the mov eax,[addy]
and it hit the bp when I clicked on the button. |
|
| Back to top |
|
 |
sponge I'm a spammer
Reputation: 1
Joined: 07 Nov 2006 Posts: 6009
|
Posted: Sun Jan 11, 2009 12:39 pm Post subject: |
|
|
| tombana wrote: | | If there is a 'leave' I don't think there needs to be an 'enter'. In masm, just create a simple function with parameters and local variables and compile that. In olly you'll see that masm will generate a push ebp; mov ebp, esp; and at the end of the function it will do leave; retn;. The leave instruction will just do mov esp, ebp; pop ebp;. | ENTER is the same thing as push ebp, mov ebp,esp. Notice the OR. Unless you were referring to BanMe. _________________
|
|
| Back to top |
|
 |
BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Mon Jan 12, 2009 8:39 am Post subject: |
|
|
dnsio you are not understanding what im saying...
im saying that code just doesnt clean stack for no reasong
so im not say look up.. im saying look for the controller function that determines that peice of code is called and stack is cleaned. it could be anywhere ...o0 it even could be virtual(with no real code except VirtualMemory with MEM_EXECUTE|MEM_WRITE..) usually its not ..
there u will find the ENTER...
im going to show u something a lil different, maybe how to locate a Controller function maybe not..iono maybe it'll help.. heres my flow chartz of my sloution ..cause im to lazy to actually do it ..o0...
this is a dll o0
Upon First Load(maybe it should be injected (SuspendedPRocessStyle))
first off allocate a chunk of growable heap in a TLS or in DllMain o0
Create a thread at intervals EnumThreads in host and
CreateThreads for each Thread(also hide's them from the debugger)
each thread has a simple disassembler that stores eip's and maybe if you so desire some current registsers...(at specific eip's or range there off ) it does this by SupendingThread() GetThreadContext Dissasmbles backwards from eip to find function head ResumeThread Sleep(0);
then once function head found look for the tail(s)... ;)repeat as necassary
oh yea also use the heap to GetContext and store eip and register's (in a more compact fashion) ..sizeof(dword)+(numofRegistersStored*4)..
maybe this can help o0
| Code: |
unsigned int GetFunctionLength(void *begin)
{
void *end = GetFunctionEnd(begin);
unsigned int delta = (unsigned int)((DWORD_PTR)end - (DWORD_PTR)begin);
delta += mlde32(end);
return delta;
}
void *GetFunctionEnd(void *func)
{
void *block = func;
TreeTrunk Tree;
Tree.MemTotalSize = 256;
Tree.MemStart = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Tree.MemTotalSize);
if(Tree.MemStart != NULL)
{
Tree.MemTotalSize = HeapSize(GetProcessHeap(),0,Tree.MemStart);
if(Tree.MemTotalSize != -1)
{
Tree.NumTotalEntry = Tree.MemTotalSize/4;
Tree.NumEntry = 0;
// ptr now points to the end of this block
void *silenttree = GetBranchListFromBlock(block, &Tree);
if(Tree.NumEntry == 0) return silenttree;
DWORD Prev = NULL;
for(DWORD i = 0; i < Tree.NumEntry; i++)
{
DWORD sz = i * sizeof(DWORD);
DWORD Limb = (*(DWORD*)Tree.MemStart + sz);
// Skip branches that jump into a block we've already
// processed.
if(Limb < *(DWORD*)silenttree || Limb == Prev)
continue;
silenttree = GetFunctionEnd(&Limb);
Prev = Limb;
}
return silenttree;
}
HeapFree(GetProcessHeap,0,Tree.MemStart);
return NULL;
}
return NULL;
}
void *GetBranchListFromBlock(void *block, TreeTrunk *Tree)
{
UCHAR *ptr = (UCHAR *)block;
// If we reach an end-point, then this block is complete
while(!IsEndPoint(ptr, block))
{
// Record all branching instructions that we encounter
void *address = GetBranchAddress(ptr);
if(address)
{
*((DWORD*)Tree->MemStart + (Tree->NumEntry * 4)) = *(DWORD*)address;
Tree->NumEntry++;
}
// Next instruction
ptr += mlde32(ptr);
}
return ptr;
}
void *GetBranchAddress(UCHAR *instr)
{
long offset = 0;
// This code will determine what type of branch it is, and
// determine the address it will branch to.
switch(*instr)
{
case INSTR_SHORTJMP:
case INSTR_RELJCX:
offset = (long)(*(char *)(instr + 1));
offset += 2;
break;
case INSTR_RELJMP:
offset = *(long *)(instr + 1);
offset += 5;
break;
case INSTR_NEAR_PREFIX:
if(*(instr + 1) >= INSTR_NEARJCC_BEGIN && *(instr + 1) <= INSTR_NEARJCC_END)
{
offset = *(long *)(instr + 2);
offset += 5;
}
break;
default:
// Check to see if it's in the valid range of JCC values.
// e.g. ja, je, jne, jb, etc..
if(*instr >= INSTR_SHORTJCC_BEGIN && *instr <= INSTR_SHORTJCC_END)
{
offset = (long)*((char *)(instr + 1));
offset += 2;
}
break;
}
if(offset == 0) return NULL;
return instr + offset;
}
bool IsEndPoint(UCHAR *instr, void *curblock)
{
void *address;
long offset;
switch(*instr)
{
case INSTR_RET:
case INSTR_RETN:
case INSTR_RETFN:
case INSTR_RETF:
return true;
break;
// The following two checks, look for an instance in which
// an unconditional jump returns us to a previous block,
// thus creating a pseudo-endpoint.
case INSTR_SHORTJMP:
offset = (long)(*(char *)(instr + 1));
address = instr + offset;
if(address <= curblock) return true;
break;
case INSTR_RELJMP:
offset = *(long *)(instr + 1);
address = instr + offset;
if(address <= curblock) return true;
break;
default:
return false;
break;
}
return false;
}
|
code is a rework of darawk origanil (i dont like CRT CLR CXYZ..)C++ and asm..and with a lil work it can be reusable for this..
so now that we collect this huges store of information lets store it in some fashion so that they can be indexed and matched up to records the next time the dll loads..
so this time we now have a set of records that matches up with the new thread we can choose to gather more information about code using code coveraging or gather better records .. or do both..
now we need some way of using it graphically...
o0
regards BanMe |
|
| Back to top |
|
 |
dnsi0 I post too much
Reputation: 0
Joined: 04 Jan 2007 Posts: 2674
|
Posted: Mon Jan 12, 2009 5:59 pm Post subject: |
|
|
sorry... what is a heap?
Ive looked at msdn but didn't get the diff between a heap and normal mem.. |
|
| Back to top |
|
 |
BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Mon Jan 12, 2009 6:07 pm Post subject: |
|
|
that was not so nice sorry dnsi0
but i think this is a oppurtunity to write a plugin for CE
so im gonna start it..
others are welcome to help im going to post what i got tommorow xD
regards BanMe |
|
| Back to top |
|
 |
|