C Windows DLL 注入记事本崩溃
C Windows DLL Injection Notepad crashes
我已经在程序中尝试了 DLL 注入 Notepad.exe
但是如果我启动我的注射器,记事本会崩溃。
这是我的注射器代码:
#include <windows.h>
#include <stdio.h>
char const Path[]="C:\Users\IEUser\Desktop\Mydll.dll";
int main(void) {
HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread;
DWORD PID;
hWnd = FindWindow(0,"Untitled - Notepad");
GetWindowThreadProcessId((HWND)hWnd, &PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0);
hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0);
WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT);
CloseHandle(hProcess);
return 0;
}
这是我的 DLL 文件代码:
#include <windows.h>
#include <stdio.h>
void InjNachricht() {
MessageBox(0, "It Works", "My DLL File", 0);
}
int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved) {
if(reason==DLL_PROCESS_ATTACH)
CreateThread(0, 0, (LPTHREAD_START_ROUTINE) InjNachricht, 0, 0, 0);
return 0;
}
我在我的 Linux 机器上用 MinGW 编译这段代码:
(Injector) i686-w64-mingw32-gcc -o Injector.exe injector.c
(DLL-File) i686-w64-mingw32-gcc -o Mydll.dll mydll.c
我还写了一个设置调试权限的函数:
void SetDebugPrivilege() {
HANDLE hProcess=GetCurrentProcess(), hToken;
TOKEN_PRIVILEGES priv;
LUID luid;
OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(0, "seDebugPrivilege", &luid);
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0);
CloseHandle(hToken);
}
如果我 运行 我的程序在我的虚拟机中:
Notepad.exe Crash
为什么记事本崩溃了?
如果我用它工作的程序注入我的 dll 文件:
enter image description here
请不要跟我来"Then I use the program instead of writing a separate injector"!!那对我没有任何帮助!!
我已经有一段时间没有做这些事情了,所以我可能会离开,但是:
- 当您 运行 远程线程时,您尝试映射 LoadLibraryA 方法。大多数现代应用程序使用 LoadLibraryW 或仅使用 LoadLibrary,后者将根据编译器模式使用默认值。
- 你用的是gcc,为什么不用微软的编译器?编译器之间可能存在映射问题,这会阻止您将 gcc 生成的代码与(可能)vcc 编译器链接起来....
希望对您有所帮助
首先,您可以使用strlen
/wcslen
(第一个是Ascii编码,第二个是Unicode编码)代替计算缓冲区的长度。我觉得比较合适
这是我为您编写的通过远程线程进行 DLL 注入的正确工作变体,作为演示示例。这是一个简单的例子,所以不要期望太多,非常简单。您可以通过使用 shell 代码注入来改进它,然后使用手动地图加载器或 LdrLoadDll。
BOOLEAN InjectDll(
HANDLE ProcessHandle,
CHAR *DllPath
)
{
BOOLEAN BlStatus = FALSE;
HANDLE ThreadHandle = 0;
PVOID LoadLibraryAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
PVOID DllMemory = 0;
SIZE_T DllLength = strlen(DllPath);
if (!ProcessHandle ||
!DllPath ||
!LoadLibraryAddress)
{
return FALSE;
}
DllMemory = VirtualAllocEx(ProcessHandle,
NULL,
DllLength,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!DllMemory)
{
return FALSE;
}
BlStatus = WriteProcessMemory(ProcessHandle,
DllMemory,
DllPath,
DllLength,
NULL);
if (!BlStatus)
{
goto cleanup;
}
ThreadHandle = CreateRemoteThread(ProcessHandle,
NULL,
0,
(LPTHREAD_START_ROUTINE)LoadLibraryAddress,
DllMemory,
0,
0);
cleanup:
if (!ThreadHandle)
{
if (DllMemory)
{
VirtualFree(DllMemory,
NULL,
MEM_RELEASE);
}
BlStatus = FALSE;
}
else
{
BlStatus = TRUE;
}
return BlStatus;
}
关于这一点,您可能对 NtOpenProcess、NtAllocateVirtualMemory、NtWriteVirtualMemory、RtlCreateUserThread/NtCreateThreadEx 和 NtAdjustPrivilegesToken 感兴趣。至于 CreateRemoteThread,它不能与其他用户帐户上的进程一起使用,而 RtlCreateUserThread/NtCreateThreadEx 两者都可以(只要您有调试权限 - SeDebugPrivilege)。
作为最后一点,请确保使用 /MT 进行编译,以便 运行-time 是静态链接的(尤其是对于您正在注入的 DLL)。如果我的示例代码对您没有帮助,并且您仍然无法解决问题,请尝试使用调试器来诊断问题。您应该已经尝试过这样做,调试器的存在是有原因的!
我已经在程序中尝试了 DLL 注入 Notepad.exe
但是如果我启动我的注射器,记事本会崩溃。 这是我的注射器代码:
#include <windows.h>
#include <stdio.h>
char const Path[]="C:\Users\IEUser\Desktop\Mydll.dll";
int main(void) {
HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread;
DWORD PID;
hWnd = FindWindow(0,"Untitled - Notepad");
GetWindowThreadProcessId((HWND)hWnd, &PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0);
hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0);
WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT);
CloseHandle(hProcess);
return 0;
}
这是我的 DLL 文件代码:
#include <windows.h>
#include <stdio.h>
void InjNachricht() {
MessageBox(0, "It Works", "My DLL File", 0);
}
int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved) {
if(reason==DLL_PROCESS_ATTACH)
CreateThread(0, 0, (LPTHREAD_START_ROUTINE) InjNachricht, 0, 0, 0);
return 0;
}
我在我的 Linux 机器上用 MinGW 编译这段代码:
(Injector) i686-w64-mingw32-gcc -o Injector.exe injector.c
(DLL-File) i686-w64-mingw32-gcc -o Mydll.dll mydll.c
我还写了一个设置调试权限的函数:
void SetDebugPrivilege() {
HANDLE hProcess=GetCurrentProcess(), hToken;
TOKEN_PRIVILEGES priv;
LUID luid;
OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(0, "seDebugPrivilege", &luid);
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0);
CloseHandle(hToken);
}
如果我 运行 我的程序在我的虚拟机中: Notepad.exe Crash
为什么记事本崩溃了? 如果我用它工作的程序注入我的 dll 文件: enter image description here
请不要跟我来"Then I use the program instead of writing a separate injector"!!那对我没有任何帮助!!
我已经有一段时间没有做这些事情了,所以我可能会离开,但是:
- 当您 运行 远程线程时,您尝试映射 LoadLibraryA 方法。大多数现代应用程序使用 LoadLibraryW 或仅使用 LoadLibrary,后者将根据编译器模式使用默认值。
- 你用的是gcc,为什么不用微软的编译器?编译器之间可能存在映射问题,这会阻止您将 gcc 生成的代码与(可能)vcc 编译器链接起来....
希望对您有所帮助
首先,您可以使用strlen
/wcslen
(第一个是Ascii编码,第二个是Unicode编码)代替计算缓冲区的长度。我觉得比较合适
这是我为您编写的通过远程线程进行 DLL 注入的正确工作变体,作为演示示例。这是一个简单的例子,所以不要期望太多,非常简单。您可以通过使用 shell 代码注入来改进它,然后使用手动地图加载器或 LdrLoadDll。
BOOLEAN InjectDll(
HANDLE ProcessHandle,
CHAR *DllPath
)
{
BOOLEAN BlStatus = FALSE;
HANDLE ThreadHandle = 0;
PVOID LoadLibraryAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
PVOID DllMemory = 0;
SIZE_T DllLength = strlen(DllPath);
if (!ProcessHandle ||
!DllPath ||
!LoadLibraryAddress)
{
return FALSE;
}
DllMemory = VirtualAllocEx(ProcessHandle,
NULL,
DllLength,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!DllMemory)
{
return FALSE;
}
BlStatus = WriteProcessMemory(ProcessHandle,
DllMemory,
DllPath,
DllLength,
NULL);
if (!BlStatus)
{
goto cleanup;
}
ThreadHandle = CreateRemoteThread(ProcessHandle,
NULL,
0,
(LPTHREAD_START_ROUTINE)LoadLibraryAddress,
DllMemory,
0,
0);
cleanup:
if (!ThreadHandle)
{
if (DllMemory)
{
VirtualFree(DllMemory,
NULL,
MEM_RELEASE);
}
BlStatus = FALSE;
}
else
{
BlStatus = TRUE;
}
return BlStatus;
}
关于这一点,您可能对 NtOpenProcess、NtAllocateVirtualMemory、NtWriteVirtualMemory、RtlCreateUserThread/NtCreateThreadEx 和 NtAdjustPrivilegesToken 感兴趣。至于 CreateRemoteThread,它不能与其他用户帐户上的进程一起使用,而 RtlCreateUserThread/NtCreateThreadEx 两者都可以(只要您有调试权限 - SeDebugPrivilege)。
作为最后一点,请确保使用 /MT 进行编译,以便 运行-time 是静态链接的(尤其是对于您正在注入的 DLL)。如果我的示例代码对您没有帮助,并且您仍然无法解决问题,请尝试使用调试器来诊断问题。您应该已经尝试过这样做,调试器的存在是有原因的!