DLL을 리버싱하다 보면 export된 함수에 hot patch를 위한 +2byte, -5byte가 있죠.
이는 API 시작에 EB F9 (JMP SHORT $-5)를 넣고, 위 5바이트에 또 JMP/CALL을 넣을 수 있게 만들어준 것입니다.(hot patch)
참고 : http://blogs.msdn.com/ishai/archive/2004/06/24/165143.aspx
왜 mov edi, edi일까, 왜 mov eax, eax / mov esi, esi도 아닌 edi 일까란 의문이 fullc0de님이랑 잡담하다가 튀어나왔지만 뭐 "nop보다는 보기 좋으니까" 말고는 결론이 안났습니다. ㅋㅋ
[그리고 혹시 vs나 platform sdk에서 저 바이너리를 넣는 옵션이 어떤건지 아는 분 계시면 알려주시면 감사하겠습니다.]
아무튼 이 binary를 모든 exported system dll apis 가 갖고 있을까? 란 의문이 들었습니다. (물론 Zw* 제외)
결론은 아니더군요.
코드와 기타 라이브러리, 결과입니다. (압축암호:'봇방지')
궁금한 dll은 argument로 주면 알아서 로드하고 조사합니당.
이는 API 시작에 EB F9 (JMP SHORT $-5)를 넣고, 위 5바이트에 또 JMP/CALL을 넣을 수 있게 만들어준 것입니다.(hot patch)
참고 : http://blogs.msdn.com/ishai/archive/2004/06/24/165143.aspx
왜 mov edi, edi일까, 왜 mov eax, eax / mov esi, esi도 아닌 edi 일까란 의문이 fullc0de님이랑 잡담하다가 튀어나왔지만 뭐 "nop보다는 보기 좋으니까" 말고는 결론이 안났습니다. ㅋㅋ
[그리고 혹시 vs나 platform sdk에서 저 바이너리를 넣는 옵션이 어떤건지 아는 분 계시면 알려주시면 감사하겠습니다.]
아무튼 이 binary를 모든 exported system dll apis 가 갖고 있을까? 란 의문이 들었습니다. (물론 Zw* 제외)
결론은 아니더군요.
코드와 기타 라이브러리, 결과입니다. (압축암호:'봇방지')
궁금한 dll은 argument로 주면 알아서 로드하고 조사합니당.
#include#include #include #include "pework.h" #include "undocumented.h" #include "disasm.h BYTE ck1[] = "\x90\x90\x90\x90\x90\x8b\xff"; // nop * 5 + mov edi, edi void main( int argc, char **argv ) { _PEB2 *peb; pework pe; dll_list_entry *entry; IMAGE_EXPORT_DIRECTORY *exp; int i, j, k; if( argc != 1 ) { for( i = 1; i < argc; i ++ ) LoadLibrary( argv[i] ); } _dis_data dis; _asm{ mov edx, dword ptr fs:[0x30] mov peb, edx } entry = ((dll_list_entry*)peb->LoaderData->InLoadOrderModuleList.Flink->Flink); while( entry && (entry->imagebase) ) { if( pe.OpenBuffer( (BYTE*)entry->imagebase, 0x1000 ) == FALSE ) { wprintf( L"%s", entry->uniModuleName.Buffer ); break; } exp = (IMAGE_EXPORT_DIRECTORY*)( pe.GetNH()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + pe.GetImageBase() ); for( i = 0; i < (int)exp->NumberOfFunctions; i ++ ) { void *func; func = (void*)( *(DWORD*)( exp->AddressOfFunctions + pe.GetImageBase() + (i*4) ) + pe.GetImageBase() ); if( func == NULL ) break; if( memcmp( (BYTE*)func - 5, ck1, 7 ) != 0 ) { // mismatch found wprintf( L"mismatch in %s::", entry->uniModuleName.Buffer ); printf( "%s\n", (char*)( *(DWORD*)( exp->AddressOfNames + (i*4) + pe.GetImageBase() ) + pe.GetImageBase() ) ); DWORD offset = 0; DWORD len; for( j = 0; j < 7; j ++ ) { if( *(BYTE*)( (DWORD)func + offset - 5 ) == 0 ) { printf( "\t00\n" ); offset ++; continue; } len = _disasm( (BYTE*)( (DWORD)func + offset - 5 ), &dis ); if( len == 0 ) break; printf( "\t" ); for( k = 0; k < (int)len; k ++ ) { printf( "%02x ", *(BYTE*)( (DWORD)func + offset + k - 5 ) ); } printf( " " ); printf( "%s\n", dis.instr_out ); offset += len; } } else { wprintf( L"match in %s::", entry->uniModuleName.Buffer ); printf( "%s\n", (char*)( *(DWORD*)( exp->AddressOfNames + (i*4) + pe.GetImageBase() ) + pe.GetImageBase() ) ); } } entry = (dll_list_entry*)(entry->InLoadOrderModuleList.Flink); } }