因為前面有用minGW編譯最小的exe檔,
想說來試試看編譯一個較小的dll檔. (不用 msvcrt.dll)
其實跟 exe 檔其實沒太大改變,
最大區別是exe檔是用 __main,
而dll檔則是要改用DllMainCRTStartup.
剩下就不要去call到c library的function,
除了kernel32.dll以外,就不需要import其他的dll檔了.
dll.c 程式碼如下:
#include <windows.h>
#define EXPORT __declspec(dllexport)
BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// Code to run when the DLL is loaded
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"Load working...\n",16, NULL,NULL);
break;
case DLL_PROCESS_DETACH:
// Code to run when the DLL is freed
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"Unload working...\n",18, NULL,NULL);
break;
case DLL_THREAD_ATTACH:
// Code to run when a thread is created during the DLL's lifetime
break;
case DLL_THREAD_DETACH:
// Code to run when a thread ends normally.
break;
}
return TRUE;
}
EXPORT void hello(void)
{
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),"Hello\n",6, NULL,NULL);
}
然後用minGW gcc去編譯,gcc -s -shared -fno-asynchronous-unwind-tables -nostartfiles -nodefaultlibs dll.c -o test.dll -lkernel32 \
-Wl,--out-implib,libtest.a -Wl,--enable-auto-image-base -Wl,--dynamicbase
#-Wl,--entry=DllMainCRTStartup
而--entry則是可以用來更換dll的entry function,不過在gcc 64bit上怪怪地,
因為我並沒需要更改這個function name,所以就不需要用了.
測試程式source code如下:
#include <windows.h>
#include <stdio.h>
void hello();
int main () {
/*Call the hello function*/
hello();
return 0;
}
用 gcc -o test.exe test.c -ltest -L.
$ ./test.exe
Load working...
Hello
Unload working...
剩下的可以用objdump觀察一下編譯出來的結果:
$ objdump -x test.dll
......
There is an import table in .idata at 0x6bec4000
The Import Tables (interpreted .idata section contents)
vma: Hint Time Forward DLL First
Table Stamp Chain Name Thunk
00004000 00004028 00000000 00000000 00004064 00004034
DLL Name: kernel32.dll
vma: Hint/Ord Member-Name Bound-To
4040 608 GetStdHandle
4050 1267 WriteFile
00004014 00000000 00000000 00000000 00000000 00000000
There is an export table in .edata at 0x6bec3000
The Export Tables (interpreted .edata section contents)
Export Flags 0
Time/Date stamp 54a555b2
Major/Minor 0/0
Name 00003032 test.dll
Ordinal Base 1
Number in:
Export Address Table 00000001
[Name Pointer/Ordinal] Table 00000001
Table Addresses
Export Address Table 00003028
Name Pointer Table 0000302c
Ordinal Table 00003030
Export Address Table -- Ordinal Base 1
[ 0] +base[ 1] 109f Export RVA
[Ordinal/Name Pointer] Table
[ 0] hello
.....
看起來完全沒問題, 就這樣了...^__^