LdrLoadDllとはWinAPIの1つで、ntdll.dllに含まれます。

普通dllをロードするのはLoadLibraryでしますが、その場合kernel32.dllをすでにロードしていなければいけません。

そのためkernel32.dllもない最低限の状態ではdllをロードできません。

しかしexeが起動するときntdll.dllは存在するため、LdrLoadDllを用いることでdllをロードすることができます。


LdrLoadDll

LdrLoadDll( 

IN PWCHAR PathToFile OPTIONAL,

 IN ULONG                Flags OPTIONAL,

 IN PUNICODE_STRING      ModuleFileName,

 OUT PHANDLE             ModuleHandle );


・PathToFile

  dllのパス

・Flags

 ファイルの配置に関するフラグ。

LOAD_LIBRARY_AS_DATAFILE とか。

・ModuleFileName

dllの名前。

・ModuleHandle

dllの先頭MZへのアドレス。


使い方

32ビットの場合は引数をスタックで渡します。

フラグは0の時しか使い方がわかりません。

__asm{

push ModuleHandle

push ModuleFileName

push 0

push 0

call LdrLoadDll

}

ModuleHandle:

ロードしたいdllの先頭アドレスを入れるためのメモリアドレス

ModuleFileName:

これを理解するのに時間がかかりました。

1バイト目にヌル文字を含まないdll名の文字数、3バイト目にヌル文字を含むdll名の文字数、

4バイト目にdll名の文字列があるアドレス。

そしてdll名はワイド文字で書くこと。


具体例としてws2_32.dllを読み込むときのModuleFileNameは、

ws2_32.dllが10文字で、ワイド文字にすると20文字のため0x14、ワイド文字のヌル文字(2バイト)を含めると22文字のため0x16。

よって

ModuleFileName[]={0x14,0,0x16,0,a,d,d,r}

dllname[]=L"ws2_32.dll"

addrのところにdllnameの先頭アドレスをいれる。




64bitでの引数の渡し方。

r9 =uType

r8 =lpCaption

rdx =lpText

rcx =hWnd

また64ビットだとメモリアドレスが8バイトのためそこら辺を変える必要があります。


おまけ

windbgでみたheavensgateのLdrLoadDllの部分