121112
.pdfИ IDAPYTHON СЛЕДОМ
УЗНА¨М АДРЕСА
def getAllAddresses():
global WINMAIN, WINMAIN_CALL, TEXT_START, TEXT_END global TEXT_SIZE, CAVE_ADDR, LOADLIBRARY
WINMAIN = ScreenEA()
refs = [f for f in CodeRefsTo( WINMAIN, False )] if len(refs) > 1:
raise Exception("Wrong WinMain") WINMAIN_CALL = refs[0]
if GetMnem( WINMAIN_CALL ) != 'call': raise Exception("Wrong WinMain call")
TEXT_START = SegStart( WINMAIN ) TEXT_END = SegEnd( WINMAIN ) TEXT_SIZE = TEXT_END - TEXT_START
temp = FindCode( SegEnd( WINMAIN ), SEARCH_NEXT ) CAVE_ADDR = temp + ItemSize( temp )
if TEXT_START + TEXT_SIZE - CAVE_ADDR < 28: raise Exception("Code cave is too small")
LOADLIBRARY = LocByName( "LoadLibraryA" ) if LOADLIBRARY == BADADDR:
raise Exception("There is no LoadLibrary import")
УЗНА¨М РАЗМЕРЫ БЛОКОВ
def getBlockSize( ea ): a = ea
ea_start = GetFunctionAttr(ea,FUNCATTR_START) while a - ea < 5:
if GetMnem(a) == "call" or GetMnem(a).find("j") == 0: return None
if ea_start != GetFunctionAttr(a,FUNCATTR_START): return None
a = FindCode(a,SEARCH_DOWN | SEARCH_NEXT) return a - ea
def getBlocks( path ):
global TEXT_START, TEXT_END
print "Building blocks. Be patient" a = TEXT_START
sizes = {}
while a < TEXT_END and a != BADADDR: if a % 4096 == 0:
print "%08x" % a sizes[a] = getBlockSize( a )
a = FindCode(a,SEARCH_DOWN | SEARCH_NEXT) f = open(path,"wb")
for k in sizes:
if sizes[k] is not None: f.write(struct.pack("l", k))
f.write(struct.pack("l", sizes[k])) f.close()
LAUNCHER.EXE V2
#include <windows.h>
void main( int argc, char **argv )
{
if ( argc < 2 )
{
MessageBox( 0, "DLL name is not specified", 0, 0 ); exit( 0 );
}
if ( LoadLibrary( argv[1] ) == NULL )
{
MessageBox( 0, "Failed to load DLL", 0, 0 );
}
}
INJECT.DLL V2
if ( inLauncher() )
{
loadTarget();
}
else
{
initSize();
doInjections();
}
void inject_code( int ea, HOOK_FUNC *our_hook ) { int size = 0;
for ( int i = 0; i < sizes_count && !size; i+=2 )
{
if ( sizes[i] == ea ) size = sizes[i+1];
}
if ( !size )
fatal_error( "Unable to inject code" ); old_inject_code( ea, our_hook, size );
}
INJECT.DLL V2
bool inLauncher()
{
char* filename = (char*) malloc( 4096 );
int n = GetModuleFileName( NULL, filename, 4096 ); _strlwr( filename );
_strlwr( TARGET_PATH );
bool result = !strstr(filename,TARGET_PATH); free( filename );
return result;
}
ЕЩЕ ОДНА ПОЛЕЗНАЯ ШТУКА
def getReturns( path ):
global TEXT_START, TEXT_END
print "Gathering return addresses. Be patient" a = TEXT_START
returns = []
while a < TEXT_END and a != BADADDR: if a % 4096 == 0:
print "%08x" % a
if GetMnem(a) == "call": returns.append( a + ItemSize( a ) )
a = FindCode(a,SEARCH_DOWN | SEARCH_NEXT) f = open(path,"wb")
for k in returns: f.write(struct.pack("l", k))
f.close()
ЧТО ПОЛУЧИЛОСЬ
Универсальный launcher.exe
Питонячий скрипт к IDA Pro, который генерирует базу блоков инструкций и исходник inject.dll
В хук-функциях inject.dll мы прозрачно работаем с регистрами и флагами
ДЕМОНСТРАЦИЯ