测试程序cpp文件:
// ClientLoadlibrary.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
typedef struct _CLientLoadLibraryParam
{
DWORD dwSize;//+0
DWORD dwStringLength; //+4
DWORD ReservedZero1;//+8
DWORD ReservedZero2;//+C
DWORD ReservedZero3;//+10
DWORD ReservedZero4;//+14
DWORD ReservedZero5;//+18 () +1A () //不需要!
DWORD ReservedZero6;//+1C
DWORD ReservedZero8;//+20
DWORD test[3]; // 占位
ULONG ptrDllString;//+30
DWORD ReservedZero11[5];
ULONG ptrApiString;//+40
WCHAR szDllName[MAX_PATH];
WCHAR szApiName[MAX_PATH];
}CLientLoadLibraryParam, *PCLientLoadLibraryParam;
extern "C" ULONG _stdcall MyClientLoadLibrary(PCLientLoadLibraryParam);
int _tmain(int argc, _TCHAR* argv[])
{
LoadLibraryA("user32.dll");
CLientLoadLibraryParam CParam = {0};
CParam.dwSize = sizeof(CLientLoadLibraryParam);
CParam.ReservedZero1 = LOAD_WITH_ALTERED_SEARCH_PATH;
CParam.ReservedZero8 = 0x1; // 绕过FixupCallbackPointers(v1);
CParam.ReservedZero6 = 0x1;
wcsncpy(CParam.szApiName, L"test", MAX_PATH);
wcsncpy(CParam.szDllName, L"d:\\1.dll", MAX_PATH);
CParam.ptrApiString = (DWORD)CParam.szApiName;
CParam.ptrDllString = (DWORD)CParam.szDllName;
MyClientLoadLibrary(&CParam);
return 0;
}
需要在VS项目中使用MASM汇编获取函数地址
test.asm
.CODE
PUBLIC MyClientLoadLibrary
MyClientLoadLibrary PROC
mov rax,gs:[60h] ; 获取PEB
mov rax,[rax+58h]; 获取PEB.KernelCallbackTable数组基址
mov rax,[rax+8*41h]; 获取KernelCallbackTable[0x41]号回调用函数USER32!_ClientLoadLibrary
call rax ; 调用 USER32!_ClientLoadLibrary
ret
MyClientLoadLibrary ENDP
END
以上程序编译成功后,再使用下面代码,编译一个要注入的DLL文件:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
extern "C" _declspec(dllexport) DWORD WINAPI test(DWORD Arg0, DWORD Arg1)
{
// nothing to do here.
return 0;
}
void do_work()
{
HANDLE hFile = CreateFileA("d:\\test.txt", GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
WCHAR lpBuffer[] = L"just test!!!";
DWORD dwWritten = 0;
WriteFile(hFile, lpBuffer, sizeof(lpBuffer),&dwWritten,NULL);
CloseHandle(hFile);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
do_work();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DLL文件编译成功后,放在D:\1.dll
然后运行编译的ClientLoadlibrary.exe,1.dll注入成功后,写入一个D:\test.txt文件。
以上两个项目需要使用x64架构编译。