From: <mod...@co...> - 2007-04-24 01:24:52
|
Hi, I'm trying to create a DLL with Dev-C++ (using the MinGW compiler). = It compiles fine, and it seems to be valid. However, when I call = LoadLibrary in another program to load the DLL, LoadLibrary fails, and GetLastError = returns 998 (ERROR_NOACCESS). Since I have used MinGW to make DLL files = successfully before, I knew that it had to be caused by something new that I was = doing. It turns out it was because I was exporting functions. The previous = DLL's that I had made only used DllMain, and didn't export anything, so for = some reason that made them work. Anyway, I followed LoadLibrary in my = debugger, and found the entry point to the DLL. I have included a partial = disassembly: 0A5D1000 55 PUSH EBP ; entry point 0A5D1001 89E5 MOV EBP,ESP 0A5D1003 57 PUSH EDI 0A5D1004 56 PUSH ESI 0A5D1005 53 PUSH EBX 0A5D1006 83EC 0C SUB ESP,0C 0A5D1009 8B7D 0C MOV EDI,[DWORD SS:EBP+C] 0A5D100C 83FF 01 CMP EDI,1 0A5D100F 0F84 AB000000 JE NetCtrl.0A5D10C0 ; implicit helper for DllMain? 0A5D1015 897C24 04 MOV [DWORD SS:ESP+4],EDI 0A5D1019 8B5D 10 MOV EBX,[DWORD SS:EBP+10] 0A5D101C 8B4D 08 MOV ECX,[DWORD SS:EBP+8] 0A5D101F 895C24 08 MOV [DWORD SS:ESP+8],EBX 0A5D1023 890C24 MOV [DWORD SS:ESP],ECX 0A5D1026 E8 A5010000 CALL NetCtrl.0A5D11D0 ; DllMain function ... 0A5D10B9 C2 0C00 RETN 0C ... 0A5D10C0 C70424 80000000 MOV [DWORD SS:ESP],80 0A5D10C7 E8 54080000 CALL NetCtrl.0A5D1920 ; bad function 0A5D10CC A3 004036A8 MOV [DWORD DS:A8364000],EAX 0A5D10D1 85C0 TEST EAX,EAX 0A5D10D3 74 6C JE SHORT NetCtrl.0A5D1141 0A5D10D5 C700 00000000 MOV [DWORD DS:EAX],0 0A5D10DB A3 104036A8 MOV [DWORD DS:A8364010],EAX 0A5D10E0 E8 8B040000 CALL NetCtrl.0A5D1570 0A5D10E5 E8 16040000 CALL NetCtrl.0A5D1500 0A5D10EA ^E9 26FFFFFF JMP NetCtrl.0A5D1015 ... 0A5D1918 0000 ADD [BYTE DS:EAX],AL 0A5D191A 0000 ADD [BYTE DS:EAX],AL 0A5D191C 0000 ADD [BYTE DS:EAX],AL 0A5D191E 0000 ADD [BYTE DS:EAX],AL 0A5D1920 FF25 D06036A8 JMP [DWORD DS:A83660D0] ; 0xA84660D0 does = not exist 0A5D1926 90 NOP 0A5D1927 90 NOP 0A5D1928 0000 ADD [BYTE DS:EAX],AL 0A5D192A 0000 ADD [BYTE DS:EAX],AL 0A5D192C 0000 ADD [BYTE DS:EAX],AL 0A5D192E 0000 ADD [BYTE DS:EAX],AL 0A5D1930 FF25 D46036A8 JMP [DWORD DS:A83660D4] 0A5D1936 90 NOP 0A5D1937 90 NOP 0A5D1938 0000 ADD [BYTE DS:EAX],AL 0A5D193A 0000 ADD [BYTE DS:EAX],AL 0A5D193C 0000 ADD [BYTE DS:EAX],AL 0A5D193E 0000 ADD [BYTE DS:EAX],AL 0A5D1940 FF25 C06036A8 JMP [DWORD DS:A83660C0] (Note that the DLL is called "NetCtrl.dll".) When the DLL is loaded, it jumps to a subroutine (possibly a helper for DllMain), and the subroutine calls what appears to be a JMP to another function. However, the JMP gets its destination from an arbitrary piece = of memory, picked seemingly at random. This doesn't make any sense at all. = I can't understand why a DLL file, which is loaded into an arbitrary = location in memory, would ever try to reference an absolute memory address. The = only solution that I can think of is that the area around 0x0A5D1920 must be = data (which is probably wrong, looking at the assembly around it), and the preceding CALL is bad.=20 A workaround I have found is to NOP out everything up 0x0A5D1026, and = then change the CALL to JMP. However, this only fixes it for DllMain, and I = would have to do it separately for every other function to make the DLL = actually work. Can anyone help me make this DLL work without hex-editing? I feel like I might be missing an option in the compiler or linker. Thanks in advance. |