带 API 挂钩"Access Violation writing location 0x0000000000"的反 dll 注入
Anti dll Injection with API Hooking "Access Violation writing location 0x0000000000"
我使用JMP指令技术,当LdrLoadDll api在我的程序中被调用时,尝试绕道进行反dll注入。我发现一个Delphi代码,工作完美,但这个vc++ 2013版本的这个代码,崩溃与
"访问违规写入位置0x0000000000"
那么,我该如何解决这个麻烦呢?有人能帮帮我吗?
提前感谢。
Delphi版本:
procedure hook(target, newfunc:pointer);
var
jmpto:dword;
OldProtect: Cardinal; // old protect in memory
begin
jmpto:=dword(newfunc)-dword(target)-5;
VirtualProtect(target, 5, PAGE_EXECUTE_READWRITE, @OldProtect);
pbyte(target)^:=$e9;
pdword(dword(target)+1)^:=jmpto;
end;
procedure myLdrLoadDll(PathToFile:PAnsiChar; Flags:variant; ModuleFileName:PAnsiChar; var ModuleHandle:THandle);
begin
MessageBox(0, 'I have blocked your attempt to inject a dll file!!', 'WARNING!', MB_OK);
ModuleHandle:=0;
end;
procedure Main;
begin
Hook(GetProcAddress(GetModuleHandle('ntdll.dll'), 'LdrLoadDll'), @myLdrLoadDll);
end;
begin
end.
尝试翻译vc++ 2013版本:
BOOL TrampolineAPI(HMODULE hModule, LPCWSTR DllName, LPCSTR ProcName, DWORD dwReplaced)
{
DWORD dwReturn;
DWORD dwOldProtect;
DWORD dwAddressToHook = (DWORD)GetProcAddress(GetModuleHandle(DllName), ProcName);
BYTE *pbTargetCode = (BYTE *)dwAddressToHook;
BYTE *pbReplaced = (BYTE *)dwReplaced;
VirtualProtect((LPVOID)dwAddressToHook, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
*pbTargetCode++ = 0xE9; // My trouble is here
*((signed int*)(pbTargetCode)) = pbReplaced - (pbTargetCode + 4);
VirtualProtect((LPVOID)dwAddressToHook, 5, PAGE_EXECUTE, &dwOldProtect);
dwReturn = dwAddressToHook + 5;
FlushInstructionCache(GetCurrentProcess(), NULL, NULL);
return TRUE;
}
void WINAPI Replaced(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
printf("Invasion!!");
}
int _tmain(int argc, _TCHAR* argv[])
{
while (true)
{
TrampolineAPI(GetModuleHandle(0), (LPCWSTR)"ntdll.DLL","LdrLoadDLL"(DWORD)Replaced);
}
return 0;
}
至少有一个问题是ANSI和Unicode字符串之间的混合。
在Win32中,有两种类型的编码- Unicode(2字节字符)和ANSI(1字节字符)。您将在ANSI中遇到的字符串类型有LPSTR
、LPCSTR
等。宽字符Unicode类型为LPWSTR
、LPCWSTR
等。
GetModuleHandleA
和GetModuleHandleW
。确定使用哪一个的方法很简单:
#ifdef UNICODE
#define GetModuleHandle GetModuleHandleW
#else
#define GetModuleHandle GetModuleHandleA
#endif //!UNICODE
在您的特殊情况下,您将使用ANSI编码的字符串常量转换为宽字符的Unicode字符串。这是未定义的行为。将主函数中的TrampolineAPI(...);
更改为以下内容:
TrampolineAPI(GetModuleHandle(0), L"ntdll.DLL", "LdrLoadDLL", (DWORD)Replaced);
L"ntdll.DLL"
是定义宽字符字符串常量的方式。这也避免了类型转换。
我还建议在整个程序中使用相同的字符串编码。这还需要您将TrampolineAPI的签名更改为
BOOL TrampolineAPI(HMODULE hModule, LPCWSTR DllName, LPCWSTR ProcName, DWORD dwReplaced) { ... }
将main中的调用改为
TrampolineAPI(GetModuleHandle(0), L"ntdll.DLL", L"LdrLoadDLL", (DWORD)Replaced);
相关文章:
- 增强基于 XML class_id的反序列化
- 使用 std::unique_ptr 的通用单链表,Visual Studio C++ Microsoft中存在未知的反
- Protobuf的反序列化功能之一可以使用Cereal重新创建吗?
- 在智能指针的反引用值上调用 std::move()
- 正则表达式括号表达式中的反斜杠
- 为什么汇编代码因我使用的反汇编程序而异
- 更改命名空间以自定义 Boost XML 的标记名称后的反序列化问题
- 删除 std::string 上的反斜杠字符时出现问题
- 尝试从 g++ 理解简单的反汇编代码
- 即使具有适当的分面,非有限浮点数的反序列化也会失败
- 如何并行化稀疏矩阵的反演
- 额外的反斜杠字符不会影响我的程序.为什么
- 标准中的反推次数::cin::ungetc
- 如何查看字符串中的反斜杠
- 如何忽略 boost::regex_search() 函数中的反斜杠字符
- C++ 漂亮的反习语;为什么
- 从XML解析字符串时添加到n的反斜杠
- 分析崩溃的反汇编 C++ 代码
- 由于NDK路径中的反斜杠,Qt Creator无法构建Android库
- 带 API 挂钩"Access Violation writing location 0x0000000000"的反 dll 注入