BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Fri May 08, 2009 8:23 pm Post subject: Thread Profiling (throwing around idea's) stay on topic plz |
|
|
Ok, so I've been kicking around idea's on how to best profile and get a unique signature (i.e. not just a code signature, but NOT excluding one either..) from user mode threads within a arbitrary process. I've looked over DYNAMORIO and Memalyze and also a few other similiar sources that touch on this topic in various ways..
I'm going to lay out the information that I would like to gather from threads to create a thread profile.
Start Address
End Address
Code Size
Number Of Calls Made
Number of Conditionals jumps
(maybe) List of API's called on each control path..
Here is a list a very easily obtainable information that will supplement the above information.
ProcessName
ProcessID
ThreadID
For the first 3 we can use hooks on BaseProcessStartThunk and BaseThreadStartThunk and GetFunctionLength, also can use this method to get the number of conditional jumps and with slight modification we can search for the call opcode as well using GetFunctionLength with modifications..
alternitivly instead of using GetFunctionLength within the hook so extensivly we could could fire up a LPC Connection to communicate the code chunk out of the process for analysis within the hooks.
these solution aren't vista freindly nor are they 64 bit compatible as of yet.. but that is all the fun of making something nowadays, i think.
All suggestions and are welcome in gathering this data, whether practical or not.
here is the implementation of the Initialization of the Profiler Hooks..
| Code: |
__checkReturn bool InitProfilerHooks(void)
{
DWORD Addr_BaseProcessStart;
DWORD Addr_BaseProcessStartThunk;
DWORD Addr_BaseThreadStart;
DWORD Addr_BaseThreadStartThunk;
BYTE SigBaseThread[7] = { 0x33,0xED,0x53,0x50,0x6A,0x00,0xE9 };
BYTE SigBaseProcess[6] = { 0x33,0xED,0x50,0x6A,0x00,0xE9 };
BYTE CodBaseThread[5] = { 0x00,0x00,0x00,0x00,0x00 };
BYTE CodBaseProcess[5] = { 0x00,0x00,0x00,0x00,0x00 };
DWORD lpflOldProtect,lpfOldProtect;
ULONG NumOfBytes = 5;
int i;
GetProcessModules();
for(i = 0;i<20;i++)
{
if(wcscmp((PWSTR)Array_ModName[i], L"kernel32.dll") == 0)
break;
}
Addr_BaseProcessStartThunk = SigSeek_FindCode((DWORD)Array_ModHandle[i],((DWORD)Array_ModHandle[i]+Array_ModSize[i]),sizeof(SigBaseProcess),(DWORD*)&SigBaseProcess);
if(Addr_BaseProcessStartThunk)
{
__asm
{
mov ebx, [eax+6]
add ebx,eax
add ebx,5
add ebx,5
mov Addr_BaseProcessStart,ebx
}
}
else
{
return FALSE;
}
Addr_BaseThreadStartThunk = SigSeek_FindCode((DWORD)Array_ModHandle[i],((DWORD)Array_ModHandle[i]+Array_ModSize[i]),sizeof(SigBaseThread),(DWORD*)&SigBaseThread);
if(Addr_BaseThreadStartThunk)
{
// extract the address of kernel32.BaseThreadStart() from jmp instruction
// destination = code location + jump offset + 5
__asm
{
mov ebx, [eax+7]
add ebx, eax // code location
add ebx, 6 //
add ebx, 5
mov Addr_BaseThreadStart, ebx
}
}
else
{
return FALSE;
}
//; hook kernel32.BaseThreadStartThunk() function
if(NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)Addr_BaseThreadStartThunk,&NumOfBytes,PAGE_EXECUTE_READWRITE,&lpflOldProtect)) &&
NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)Addr_BaseProcessStartThunk,&NumOfBytes,PAGE_EXECUTE_READWRITE,&lpfOldProtect)))
{
if(NT_SUCCESS(NtFlushInstructionCache(NtCurrentProcess(),(PVOID)&Addr_BaseProcessStartThunk,5)) &&
NT_SUCCESS(NtFlushInstructionCache(NtCurrentProcess(),(PVOID)&Addr_BaseThreadStartThunk, 5)))
{
__asm
{
lds esi, Addr_BaseThreadStartThunk
les edi, CodBaseThread
mov ecx,0x5
rep movsb
mov edi, Addr_BaseThreadStartThunk
mov eax, Hook_BaseThreadStartThunk
sub eax, edi
sub eax,5
mov byte ptr [edi+0], 0xE9// ; jmp short
mov dword ptr [edi+1], eax
mov esi, Addr_BaseProcessStartThunk
les edi, CodBaseProcess
mov ecx,0x5
rep movsb
mov edi, Addr_BaseProcessStartThunk
mov eax, Hook_BaseProcessStartThunk
sub eax,edi
sub eax,5
mov byte ptr [edi+0],0xE9
mov dword ptr [edi+1],eax
}
}
else
{
return FALSE;
}
if(NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)Addr_BaseThreadStartThunk,&NumOfBytes,lpflOldProtect,&lpflOldProtect)) &&
NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)Addr_BaseProcessStartThunk,&NumOfBytes,lpfOldProtect,&lpfOldProtect)))
{
return TRUE;
}
}
return FALSE;
}
|
input appreciated...
references:
DYNAMORIO http://www.cag.lcs.mit.edu/dynamorio/
Memalyze http://www.uninformed.org/?v=7&a=1&t=pdf/
EasyHook http://www.codeplex.com/easyhook/
Regards BanMe
_________________
don't +rep me..i do not wish to have "status" or "recognition" from you or anyone.. thank you. |
|