From 72c9906325874a9dff81caefaf768660c939545c Mon Sep 17 00:00:00 2001 From: devseed Date: Fri, 5 Apr 2024 19:23:07 +0900 Subject: [PATCH] improve the test case, add comment for not working situation --- project/windll_winhook/Makefile | 2 +- project/windll_winhook/src/libwinhook_test.c | 1 + project/windll_winpe/Makefile | 4 +- project/windll_winpe/src/libwinpe_test.c | 38 ++++++++++++++--- src/winpe.h | 44 +++++++++++++------- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/project/windll_winhook/Makefile b/project/windll_winhook/Makefile index 86130b7..45a2963 100644 --- a/project/windll_winhook/Makefile +++ b/project/windll_winhook/Makefile @@ -1,5 +1,5 @@ # build example -# make libwinhook helloexe hellodll libwinhook_test CC=i686-w64-mingw32-gcc BUILD_TYPE=32d +# make libwinhook helloexe hellodll libwinhook_test CC=i686-w64-mingw32-gcc BUILD_TYPE=32d # make libwinhook helloexe hellodll libwinhook_test CC=x86_64-w64-mingw32-gcc BUILD_TYPE=64d # wine build/libwinhook_test32d.exe && wine build/libwinhook_test64d.exe diff --git a/project/windll_winhook/src/libwinhook_test.c b/project/windll_winhook/src/libwinhook_test.c index f690d48..ae6ce64 100644 --- a/project/windll_winhook/src/libwinhook_test.c +++ b/project/windll_winhook/src/libwinhook_test.c @@ -141,5 +141,6 @@ int main(int argc, char *argv[]) test_searchpattern2(); test_startexeinject(); test_windyn(); + printf("%s finish!\n", argv[0]); return 0; } \ No newline at end of file diff --git a/project/windll_winpe/Makefile b/project/windll_winpe/Makefile index d2e1bad..9e49d2a 100644 --- a/project/windll_winpe/Makefile +++ b/project/windll_winpe/Makefile @@ -1,5 +1,5 @@ # build example -# make libwinpe libwinpe_test CC=i686-w64-mingw32-gcc BUILD_TYPE=32d +# make libwinpe libwinpe_test CC=i686-w64-mingw32-gcc BUILD_TYPE=32d # make libwinpe libwinpe_test CC=x86_64-w64-mingw32-gcc BUILD_TYPE=64d # wine build/libwinpe_test32d.exe && wine build/libwinpe_test64d.exe @@ -27,7 +27,7 @@ endif ifneq (,$(findstring d, $(BUILD_TYPE))) CFLAGS+=-g -D_DEBUG else -CFLAGS+=-Os +CFLAGS+=-O3 endif ifneq (,$(findstring tcc, $(CC))) LDFLAGS= # tcc can not remove at at stdcall in i686 diff --git a/project/windll_winpe/src/libwinpe_test.c b/project/windll_winpe/src/libwinpe_test.c index 4f6cd3f..55241d9 100644 --- a/project/windll_winpe/src/libwinpe_test.c +++ b/project/windll_winpe/src/libwinpe_test.c @@ -9,45 +9,71 @@ void test_findkernel32() { void *kerenl32 = winpe_findkernel32(); - assert(kerenl32==GetModuleHandleA("kernel32")); printf("[test_findkernel32] kernel32=%p\n", kerenl32); + assert(kerenl32==GetModuleHandleA("kernel32")); +} + +void test_findloadlibrarya() +{ + + void *func = (void*)LoadLibraryA; + void *func2 = winpe_findloadlibrarya(); + printf("[test_findloadlibrarya] LoadLibraryA=%p\n", func2); + assert(func==func2); +} + +void test_findgetprocaddress() +{ + void *func = (void*)GetProcAddress; + void *func2 = winpe_findgetprocaddress(); + printf("[test_findgetprocaddress] GetProcAddress=%p\n", func2); + assert(func==func2); } void test_findmodulea(const char *modname) { void* hmod = (void*)GetModuleHandleA(modname); void* hmod2 = (void*)winpe_findmodulea(modname); - assert(hmod==hmod2); printf("[test_findmodulea] modname=%s hmod=%p\n", modname, hmod2); + assert(hmod==hmod2); } void test_memforwardexp(HMODULE hmod, const char *funcname) { size_t expva = (size_t)GetProcAddress(hmod, funcname); size_t exprva = (size_t)winpe_memfindexp(hmod, funcname) - (size_t)hmod; + printf("%x\n", exprva); void *func = winpe_memforwardexp(hmod, exprva, - LoadLibraryA, (PFN_GetProcAddress)winpe_memfindexp); + (PFN_LoadLibraryA)winpe_findloadlibrarya(), + (PFN_GetProcAddress)winpe_memfindexp); void *func2 = winpe_memGetProcAddress(hmod, funcname); - assert(exprva!=0 && (size_t)func==expva && func!=NULL && func2==func); - printf("[test_memforwardexp] hmod=%p funcname=%s func=%p\n", hmod, funcname, func2); + printf("[test_memforwardexp] hmod=%p funcname=%s func=%p func2=%p\n", + hmod, funcname, func, func2); + assert(exprva!=0); + assert((size_t)func==expva); + assert(func2==func); } void test_memGetProcAddress(HMODULE hmod, const char *funcname) { void* func = (void*)GetProcAddress(hmod, funcname); void *func2 = (void*)winpe_memGetProcAddress(hmod, funcname); + printf("[test_memGetProcAddress] hmod=%p funcname=%s func=%p func2=%p\n", + hmod, funcname, func, func2); assert(func==func2); - printf("[test_memGetProcAddress] hmod=%p funcname=%s func=%p\n", hmod, funcname, func2); } int main(int argc, char *argv[]) { test_findkernel32(); + test_findloadlibrarya(); + test_findgetprocaddress(); test_findmodulea("kernel32.dll"); HMODULE hkernel32 = LoadLibraryA("kernel32.dll"); test_memforwardexp(hkernel32, "LoadLibraryA"); test_memforwardexp(hkernel32, "InitializeSListHead"); test_memforwardexp(hkernel32, "GetSystemTimeAsFileTime"); test_memGetProcAddress(hkernel32, "GetProcessMitigationPolicy"); + printf("%s finish!\n", argv[0]); return 0; } \ No newline at end of file diff --git a/src/winpe.h b/src/winpe.h index dda12a4..c70a1fe 100644 --- a/src/winpe.h +++ b/src/winpe.h @@ -566,11 +566,24 @@ BOOL STDCALL winpe_memFreeLibraryEx(void *mempe, PROC STDCALL winpe_memGetProcAddress(void *mempe, const char *funcname) { + // this function might failed if inline and -Os, -O3, if in dll function, use printf might help void* expva = winpe_memfindexp(mempe, funcname); - size_t exprva = (size_t)((uint8_t*)expva - (uint8_t*)mempe); - return (PROC)winpe_memforwardexp(mempe, exprva, // to avoid infinity loop - (PFN_LoadLibraryA)winpe_findloadlibrarya(), - (PFN_GetProcAddress)winpe_findgetprocaddress()); + size_t exprva = (size_t)expva - (size_t)mempe; + // printf("[winpe_memGetProcAddress] expva=%p\n", expva); + + // use pfnLoadLibraryA, pfnGetProcAddress to avoid infinity loop + void *hmod_kernel32 = winpe_findkernel32(); + char name_GetProcAddress[] = {'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', '\0'}; + char name_LoadLibraryA[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', '\0'}; + char *name[2] = {name_LoadLibraryA, name_GetProcAddress}; + void *func[2] = {NULL, NULL}; + for(int i=0; i<2;i++) + { + func[i] = winpe_memfindexp(hmod_kernel32, name[i]); + } + PFN_LoadLibraryA pfnLoadLibraryA = (PFN_LoadLibraryA)func[0]; + PFN_GetProcAddress pfnGetProcAddress = (PFN_GetProcAddress)func[1]; + return (PROC)winpe_memforwardexp(mempe, exprva, pfnLoadLibraryA, pfnGetProcAddress); } // PE query functions @@ -700,17 +713,16 @@ void* STDCALL winpe_findmoduleaex(PPEB peb, const char *modulename) PROC winpe_findloadlibrarya() { - // return (PROC)LoadLibraryA; - HMODULE hmod_kernel32 = (HMODULE)winpe_findkernel32(); + // -Os might make this function not current, such as strcpy(Flink, "LoadLibraryA"); + void* hmod_kernel32 = winpe_findkernel32(); char name_LoadLibraryA[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', '\0'}; // suppose exp no forward, to avoid recursive - return (PROC)winpe_memfindexp((void*)hmod_kernel32, name_LoadLibraryA); + return (PROC)winpe_memfindexp(hmod_kernel32, name_LoadLibraryA); } PROC winpe_findgetprocaddress() { - // return (PROC)GetProcAddress; - HMODULE hmod_kernel32 = (HMODULE)winpe_findkernel32(); + void* hmod_kernel32 = winpe_findkernel32(); char name_GetProcAddress[] = {'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', '\0'}; return (PROC)winpe_memfindexp(hmod_kernel32, name_GetProcAddress); } @@ -1012,21 +1024,21 @@ void* STDCALL winpe_memforwardexp(void *mempe, size_t exprva, PFN_LoadLibraryA pfnLoadLibraryA, PFN_GetProcAddress pfnGetProcAddress) { // this function might have infinite loop - // such as this situation // kerenl32.dll, GetProcessMitigationPolicy -> api-ms-win-core-processthreads-l1-1-1.dll -> kerenl32.dll, GetProcessMitigationPolicys size_t dllbase = (size_t)mempe; while (1) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)dllbase; - PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((uint8_t*)dllbase + pDosHeader->e_lfanew); + PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((uint8_t*)dllbase + pDosHeader->e_lfanew); PIMAGE_OPTIONAL_HEADER pOptHeader = &pNtHeader->OptionalHeader; PIMAGE_DATA_DIRECTORY pDataDirectory = pOptHeader->DataDirectory; PIMAGE_DATA_DIRECTORY pExpEntry = &pDataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - if(exprva>=pExpEntry->VirtualAddress && exprva<= pExpEntry->VirtualAddress + pExpEntry->Size) + if(exprva >= pExpEntry->VirtualAddress && exprva < pExpEntry->VirtualAddress + pExpEntry->Size) { char namebuf[MAX_PATH]; - char *dllname = (char *)(dllbase + exprva); + char *dllname = (char*)(dllbase + exprva); char *funcname = dllname; + //printf("[winpe_memforwardexp] dllname=%s funcname=%s\n", dllname, funcname); int i=0, j=0; while(dllname[i]!=0) { @@ -1041,7 +1053,7 @@ void* STDCALL winpe_memforwardexp(void *mempe, size_t exprva, } else { - namebuf[j]=dllname[i]; + namebuf[j] = dllname[i]; } i++; j++; @@ -1049,8 +1061,8 @@ void* STDCALL winpe_memforwardexp(void *mempe, size_t exprva, namebuf[j] = '\0'; dllname = namebuf; dllbase = (size_t)pfnLoadLibraryA(dllname); - exprva = (size_t)pfnGetProcAddress((HMODULE)dllbase, funcname); - exprva -= dllbase; + size_t expva = (size_t)pfnGetProcAddress((HMODULE)dllbase, funcname); + exprva = expva - dllbase; } else {