товарищи кодеры просьба помочь я наваял библиотечку, которая при подрузке (дллмаин) читает из конфига имена библиотек, и подгружает их себе в процесс, а затем вызавет их дллмаин. вродебы (как мне кажется) мапит библиотеку оно нормально. проблема возникает при вызове дллмаин.... для теста использовал простенькую подгружаемую длл, с 1 функцией, ее дллмаин вызывает мессажбокс. после того как выскакивает окошко соответствуещего мессажбокса происходит глюк. вроде бы срывается стек. но хоть убейте не пойму где
пятая функция в том классе, что был в предыдущем сорце someone что за вопрос? где код? или нужен магический шар?
Код (Text): HMODULE xLoadLibrary(PBYTE pbDllBuff,DWORD reason) { HMODULE hRet = 0; DWORD dwImageBase, dwImageSize, dwHeadersSize, dwImageBaseDelta; PIMAGE_NT_HEADERS pImageNtHeaders; PBYTE pbImage = NULL; DWORD dllEntry; TDLLENTRY entrypoint; __try { pImageNtHeaders = (PIMAGE_NT_HEADERS) (pbDllBuff + ((PIMAGE_DOS_HEADER)pbDllBuff)->e_lfanew); dwImageBase = pImageNtHeaders->OptionalHeader.ImageBase; dwImageSize = pImageNtHeaders->OptionalHeader.SizeOfImage; dwHeadersSize = pImageNtHeaders->OptionalHeader.SizeOfHeaders; dllEntry = pImageNtHeaders->OptionalHeader.AddressOfEntryPoint; DWORD dwNewBase = dwImageBase; while (pbImage == NULL) { pbImage = (PBYTE)VirtualAlloc((LPVOID)dwNewBase, dwImageSize, MEM_RESERVE, PAGE_NOACCESS); dwNewBase += 0x10000; } dwImageBaseDelta = dwNewBase - dwImageBase - 0x10000; PBYTE pbHeaders = (PBYTE)VirtualAlloc(pbImage, dwHeadersSize, MEM_COMMIT, PAGE_READWRITE); memcpy(pbHeaders, pbDllBuff, dwHeadersSize); DWORD dwOldProtect; VirtualProtect(pbHeaders, dwHeadersSize, PAGE_READONLY, &dwOldProtect); PIMAGE_SECTION_HEADER pImageSectionHeader = (PIMAGE_SECTION_HEADER) (pImageNtHeaders->FileHeader.SizeOfOptionalHeader + (long)&(pImageNtHeaders->OptionalHeader)); PBYTE pbMem = NULL; DWORD dwRawSectionSize = 0; for (int i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++) { if (pImageSectionHeader->SizeOfRawData > pImageSectionHeader->Misc.VirtualSize) dwRawSectionSize = pImageSectionHeader->Misc.VirtualSize; else dwRawSectionSize = pImageSectionHeader->SizeOfRawData; pbMem = (PBYTE)VirtualAlloc((LPVOID)RVATOVA(pbImage, pImageSectionHeader->VirtualAddress), pImageSectionHeader->Misc.VirtualSize, MEM_COMMIT, PAGE_READWRITE); ZeroMemory(pbMem, pImageSectionHeader->Misc.VirtualSize); memcpy(pbMem, (void *)RVATOVA(pbDllBuff, pImageSectionHeader->PointerToRawData), dwRawSectionSize); pImageSectionHeader++; } for (int m = 0; m < pImageNtHeaders->FileHeader.NumberOfSections; m++) { VirtualProtect((LPVOID)RVATOVA(pbImage, pImageSectionHeader[m].VirtualAddress), pImageSectionHeader[m].Misc.VirtualSize, GetSectionProtection(pImageSectionHeader[m].Characteristics), &dwOldProtect); } if (!ProcessRelocs((long)pbImage, dwImageBaseDelta)) goto end; if (!ProcessImports((long)pbImage)) goto end; MessageBoxA(0,"ok",0,0); entrypoint=(TDLLENTRY)(dllEntry+(DWORD)pbImage); entrypoint((HMODULE)pbImage,DLL_PROCESS_ATTACH,NULL); } __except (EXCEPTION_EXECUTE_HANDLER) { goto end; } hRet = (HMODULE)pbImage; end: return hRet; } извините собирался вторым постом код кинуть, отвлекся не успел дело в том что без вызова дллентри из подгружаемой библиотеки такого глюка замечено не было и вроде бы все работало нормально
entrypoint=(TDLLENTRY)(dllEntry+(DWORD)pbImage); entrypoint((HMODULE)pbImage,DLL_PROCESS_ATTACH,NULL); А че, разве это надо делать? Винда вроде как сама вызовет DLL Main подгружаемой библиотеки...
n0name pushick отжиг засчитан) someone уверен, что остальные функции работают нормально, особенно обработка релоков?
блин я пользовался всем этим "г" раньше, просто не нужно было дллмаин вызывать да и все. а теперь возникла необходимость. вызываю. ОНА ВЫПОЛНЯЕТСЯ (тестю на либе написаной на паскале которая вызывает мессажбокс при загрузке и все.) и сразу потом все нафик вылетает (после того мессажбокса из подгружаемой либы) и хз шо с ним.
значит у тебя проблемы с calling convention, в пользу этой причины еще и говорит то, что слетает стек. покажи объявление типа TDLLENTRY
хм.. ну тогда неясно ни разу. если хочешь, кинь полные сорсы твоего чуда природы и тестовую дллку, посмотрим что где падает.
а отлаживать не пробовал? всё таки иногда помогает, тем более что если DllMain достаточно простаю, посмотри где падает.
хз. внимание вопрос на засыпку как отлаживать длл? а особенно как проследить загрузку одной длл из другой?
внимание вопрос на засыпку: про OllyDbg слышал? это раз два - скажи-ка, а чем по-твоему отличается отладка длл от отладки проги? Лирическое отступление: складывается такое впечатление, что народ сюда приходит с мыслью - ооо, они шаманы, я их попрошу посмотреть где ошибка, они посмотрят и сразу скажут что не так и как исправить, у них наверное есть какие-то супербубны и мегазаклинания, которые нужно петь, танцуя вокруг костра =\
да не занимался я раньше с длл были у меня эти исходники готовые, рабочие. надо было прикрутить туда вызов дллмаин да и все. сел колупал-колупал не получается а вдруг ктото с чемто подобным воевал? дело в том что без вызова дллмаин все работает отлично. а как только Код (Text): dllEntry = pImageNtHeaders->OptionalHeader.AddressOfEntryPoint; entrypoint=(TDLLENTRY)(dllEntry+(DWORD)pbImage); entrypoint((HMODULE)pbImage,DLL_PROCESS_ATTACH,NULL); вот это добавил... запускает оно дллмаин.... а потом тупо вылетает и все
Код (Text): #define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset))) DWORD GetSectionProtection(DWORD); BOOL ProcessRelocs(unsigned long, DWORD); typedef BOOL (WINAPI* TDLLENTRY)(HMODULE, DWORD,LPVOID); PVOID myalloc (DWORD size) { PVOID mem; mem=VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_EXECUTE_READWRITE); memset(mem,0,size); return mem; } BOOL myfree (PVOID mem) { return VirtualFree(mem,0,MEM_DECOMMIT); } PVOID decrypt(PVOID data,DWORD size,PCHAR key) { PVOID r; r=myalloc(size); memcpy(r,data,size); return r; } DWORD GetSectionProtection(DWORD SC) { DWORD result=0; if (SC && IMAGE_SCN_MEM_NOT_CACHED != 0) result = result || PAGE_NOCACHE; if (SC && IMAGE_SCN_MEM_EXECUTE != 0) { if (SC && IMAGE_SCN_MEM_READ != 0) { if (SC && IMAGE_SCN_MEM_WRITE != 0) result = result || PAGE_EXECUTE_READWRITE; else result = result || PAGE_EXECUTE_READ; } else if (SC && IMAGE_SCN_MEM_WRITE != 0) result = result || PAGE_EXECUTE_WRITECOPY; else result = result || PAGE_EXECUTE; } else if (SC && IMAGE_SCN_MEM_READ != 0) { if (SC && IMAGE_SCN_MEM_WRITE != 0) result = result || PAGE_READWRITE; else result = result || PAGE_READONLY; } else if (SC || IMAGE_SCN_MEM_WRITE != 0) result = result || PAGE_WRITECOPY; else result = result || PAGE_NOACCESS; return result; } BOOL ProcessRelocs(unsigned long hMap, DWORD dwImageBaseDelta) { PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)(hMap + ((PIMAGE_DOS_HEADER)hMap)->e_lfanew); unsigned long pImageBaseRelocation = (unsigned long)(RVATOVA(hMap, pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)); // __try { while (((PIMAGE_BASE_RELOCATION)pImageBaseRelocation)->VirtualAddress != 0) { int number = (((PIMAGE_BASE_RELOCATION)pImageBaseRelocation)->SizeOfBlock - 8) / 2; WORD* Rel = (WORD *)(pImageBaseRelocation + 8); for (int i = 0; i < number; i++) { *(PDWORD)(RVATOVA(hMap, ((PIMAGE_BASE_RELOCATION)pImageBaseRelocation)->VirtualAddress + ((0x0FFF)&(Rel[i])))) += dwImageBaseDelta; } pImageBaseRelocation += ((PIMAGE_BASE_RELOCATION)pImageBaseRelocation)->SizeOfBlock; } } /*__except (EXCEPTION_EXECUTE_HANDLER) { return FALSE; } */ return TRUE; } BOOL ProcessImports(unsigned long hMap) { IMAGE_THUNK_DATA32 *pThunk; HMODULE hLibModule; PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)(hMap + ((PIMAGE_DOS_HEADER)hMap)->e_lfanew); PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOVA(hMap, pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); //__try { while (pImageImportDescriptor->Name != 0) { char *name = (char *)RVATOVA(hMap, pImageImportDescriptor->Name); hLibModule = LoadLibraryA(name); if (hLibModule == NULL) return FALSE; if (pImageImportDescriptor->TimeDateStamp == 0) pThunk = (IMAGE_THUNK_DATA32 *)RVATOVA(hMap, pImageImportDescriptor->FirstThunk); else pThunk = (IMAGE_THUNK_DATA32 *)RVATOVA(hMap, pImageImportDescriptor->OriginalFirstThunk); while (pThunk->u1.Ordinal != 0) { DWORD dwProcAddr = 0; char *ImportedName; if (((pThunk->u1.Ordinal) & 0x80000000) != 0) { dwProcAddr = (DWORD)GetProcAddress(hLibModule, (char *)(pThunk && 0xFFFF)); } else { PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME) RVATOVA(hMap, pThunk->u1.AddressOfData); ImportedName = (char *)&pImageImportByName->Name; dwProcAddr = (DWORD)GetProcAddress(hLibModule, ImportedName); } *(PDWORD)pThunk = dwProcAddr; pThunk++; } pImageImportDescriptor++; } } /*__except (EXCEPTION_EXECUTE_HANDLER) { return FALSE; } */ return TRUE; } DWORD xGetProcAdress(long hMap, int num) { PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)(hMap + ((PIMAGE_DOS_HEADER)hMap)->e_lfanew); PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RVATOVA(hMap, pImageNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress); PDWORD AddressOfFunctions = (PDWORD)RVATOVA(hMap, pImageExportDirectory->AddressOfFunctions); for (DWORD i = 0; i < pImageExportDirectory->NumberOfFunctions; i++) if (i == num - 1) return (DWORD)RVATOVA(hMap, AddressOfFunctions[i]); return 0; } HMODULE xLoadLibrary(PBYTE pbDllBuff,DWORD reason) { HMODULE hRet = 0; DWORD dwImageBase, dwImageSize, dwHeadersSize, dwImageBaseDelta; PIMAGE_NT_HEADERS pImageNtHeaders; PBYTE pbImage = NULL; DWORD dllEntry; TDLLENTRY entrypoint; __try { pImageNtHeaders = (PIMAGE_NT_HEADERS) (pbDllBuff + ((PIMAGE_DOS_HEADER)pbDllBuff)->e_lfanew); dwImageBase = pImageNtHeaders->OptionalHeader.ImageBase; dwImageSize = pImageNtHeaders->OptionalHeader.SizeOfImage; dwHeadersSize = pImageNtHeaders->OptionalHeader.SizeOfHeaders; dllEntry = pImageNtHeaders->OptionalHeader.AddressOfEntryPoint; DWORD dwNewBase = dwImageBase; while (pbImage == NULL) { pbImage = (PBYTE)VirtualAlloc((LPVOID)dwNewBase, dwImageSize, MEM_RESERVE, PAGE_NOACCESS); dwNewBase += 0x10000; } dwImageBaseDelta = dwNewBase - dwImageBase - 0x10000; PBYTE pbHeaders = (PBYTE)VirtualAlloc(pbImage, dwHeadersSize, MEM_COMMIT, PAGE_READWRITE); memcpy(pbHeaders, pbDllBuff, dwHeadersSize); DWORD dwOldProtect; VirtualProtect(pbHeaders, dwHeadersSize, PAGE_READONLY, &dwOldProtect); PIMAGE_SECTION_HEADER pImageSectionHeader = (PIMAGE_SECTION_HEADER) (pImageNtHeaders->FileHeader.SizeOfOptionalHeader + (long)&(pImageNtHeaders->OptionalHeader)); PBYTE pbMem = NULL; DWORD dwRawSectionSize = 0; for (int i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++) { if (pImageSectionHeader->SizeOfRawData > pImageSectionHeader->Misc.VirtualSize) dwRawSectionSize = pImageSectionHeader->Misc.VirtualSize; else dwRawSectionSize = pImageSectionHeader->SizeOfRawData; pbMem = (PBYTE)VirtualAlloc((LPVOID)RVATOVA(pbImage, pImageSectionHeader->VirtualAddress), pImageSectionHeader->Misc.VirtualSize, MEM_COMMIT, PAGE_READWRITE); ZeroMemory(pbMem, pImageSectionHeader->Misc.VirtualSize); memcpy(pbMem, (void *)RVATOVA(pbDllBuff, pImageSectionHeader->PointerToRawData), dwRawSectionSize); pImageSectionHeader++; } for (int m = 0; m < pImageNtHeaders->FileHeader.NumberOfSections; m++) { VirtualProtect((LPVOID)RVATOVA(pbImage, pImageSectionHeader[m].VirtualAddress), pImageSectionHeader[m].Misc.VirtualSize, GetSectionProtection(pImageSectionHeader[m].Characteristics), &dwOldProtect); } if (!ProcessRelocs((long)pbImage, dwImageBaseDelta)) goto end; if (!ProcessImports((long)pbImage)) goto end; MessageBoxA(0,"ok",0,0); entrypoint=(TDLLENTRY)(dllEntry+(DWORD)pbImage); entrypoint((HMODULE)pbImage,DLL_PROCESS_ATTACH,NULL); // MessageBoxA(0,"ok",0,0); MessageBoxA(0,"ls",0,0); } __except (EXCEPTION_EXECUTE_HANDLER) { MessageBoxA(0,"ffuck",0,0); goto end; } hRet = (HMODULE)pbImage; end: return hRet; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { HANDLE hfile=INVALID_HANDLE_VALUE; PVOID fdata=NULL; PCHAR fname=NULL; HANDLE hcfile=INVALID_HANDLE_VALUE; PCHAR cfdata=NULL; PCHAR cfname=NULL; PCHAR cryptdata=NULL; DWORD i,j,k; PCHAR ss; DWORD size,dsize=0; OFSTRUCT os; if(ul_reason_for_call!=DLL_PROCESS_ATTACH&&ul_reason_for_call!=DLL_THREAD_ATTACH) { MessageBoxA(0,"UNLOADING",0,0); return true; } //--------------------------------------------------read from config file and decrypt it //MessageBoxA(0,"1",0,0); cfname=(PCHAR)myalloc(strlen("C:\\fconfig.txt")); //MessageBoxA(0,"2",0,0); strcpy(cfname,"C:\\fconfig.txt"); hcfile=CreateFileA(cfname,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); if(hcfile==INVALID_HANDLE_VALUE) return false;//MessageBoxA(0,"cantopenfile",0,0); //MessageBoxA(0,"3",0,0); size=GetFileSize(hcfile,NULL); cryptdata=(PCHAR)myalloc(size); if(!ReadFile(hcfile,cryptdata,size,&i,NULL)) return false;//MessageBoxA(0,"cantreadfile",0,0); cfdata=(PCHAR)decrypt((PVOID)cryptdata,size,""); myfree(cryptdata); //MessageBoxA(0,cfdata,0,0); i=0; //MessageBoxA(0,cfname,0,0); ss=strstr(&(cfdata[i]),"dll "); fname=NULL; while(ss!=NULL) { MessageBoxA(0,"next",0,0); i=ss-cfdata; i+=4; while(cfdata[i]==' '&&i<=size) i++; j=i; while(cfdata[i]!=';'&&i<=size) i++; if(fname!=NULL) myfree(fname); fname=(PCHAR)myalloc(i-j+1); strncpy(fname,&cfdata[j],i-j); //MessageBoxA(0,fname,0,0); hfile=CreateFileA(fname,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); dsize=GetFileSize(hfile,NULL); cryptdata=(PCHAR)myalloc(dsize); if(!ReadFile(hfile,cryptdata,dsize,&i,NULL)) return false;//MessageBoxA(0,"cantreadfile",0,0); fdata=decrypt(cryptdata,dsize,""); if(cryptdata!=NULL)myfree(cryptdata); MessageBoxA(0,"try","ok",0); xLoadLibrary((PBYTE)fdata,ul_reason_for_call); MessageBoxA(0,"decrypt","ok",0); if(fdata!=NULL)myfree(fdata); MessageBoxA(0,"this","ok",0); ss=strstr(&cfdata[i],"dll "); } //--------------------------------------------------loop read and load modules //--------------------------------------------------cleanup memory if(fname!=NULL) myfree(fname); if(cfdata!=NULL) myfree(cfdata); if(hcfile!=INVALID_HANDLE_VALUE) CloseHandle(hcfile); if(hfile!=INVALID_HANDLE_VALUE) CloseHandle(hfile); return TRUE; }
а может у когото есть шото подобное? готовое я бы глянул как там сделано и может нашел бы таки ошибочку?