我正在处理两件新事:写一个DLL并在另一个进程中注入它。我想我注入成功,因为如果我尝试删除它,我会收到一条消息,告诉我它被其他程序使用。
我在Visual Studio 2008 http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx中执行了这些步骤,但是我用C编写了它,而不是C ++。
这是代码
DWORD
APIENTRY
DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
printf("Hello World\n");
Sleep(5000); // added this to make sure I see it when it happens
return TRUE;
}
我创建了一个引用DLL的应用程序,就像在MSDN文档中说的那样,它可以工作(它打印Hello World)。
在我的DLL注入程序的每一步,我检查错误并打印它们。所以我知道没有任何功能失败。 我检查退出代码,它是1927086080,我不知道是什么意思。 我不知道是否需要它,但这是我的程序的C源。
#include <stdio.h>
#include <windows.h>
#include <string.h>
int main(int argc, TCHAR* argv[])
{
DWORD procId = 0;
DWORD pathLen = 0;
DWORD writeProcMemory = 0;
DWORD exitCode = 0;
HANDLE hProc = NULL;
HANDLE hDll = NULL;
HANDLE hThread = NULL;
LPVOID baseAdr = NULL;
LPVOID fAdr = NULL;
procId = atoi((char*)argv[1]);
pathLen = strlen((LPCSTR)argv[2]);
if(0 == pathLen)
{
printf("Check DLL path\n");
return 0;
}
// Open process
hProc = OpenProcess(PROCESS_ALL_ACCESS,
0,
procId);
if(NULL == hProc)
{
printf("OpenProcess failed\nGetLastError() = %d\n",
GetLastError());
return 0;
}
// Allocate memory
baseAdr = VirtualAllocEx(hProc,
0,
pathLen + 1,
MEM_COMMIT,
PAGE_READWRITE);
if(NULL == baseAdr)
{
printf("VirtualAllocEx failed\nGetLastError() = %d\n",
GetLastError());
CloseHandle(hProc);
return 0;
}
// write my dll path in the memory I just allocated
if(!WriteProcessMemory(hProc,
baseAdr,
argv[2],
pathLen + 1,
0))
{
printf("WriteProcessMemory failed\nGetLastError() = %d\n",
GetLastError());
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// get kernel32.dll
hDll = LoadLibrary(TEXT("kernel32.dll"));
if(NULL == hDll)
{
printf("LoadLibrary failed\nGetLastError() = %d\n",
GetLastError());
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// get LoadLibraryA entry point
fAdr = GetProcAddress(hDll,
"LoadLibraryA");
if(NULL == fAdr)
{
printf("GetProcAddress failed\nGetLastError() = %d\n",
GetLastError());
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// create remote thread
hThread = CreateRemoteThread(hProc,
0,
0,
fAdr,
baseAdr,
0,
0);
if(NULL == hThread)
{
printf("CreateRemoteThread failed\nGetLastError() = %d\n",
GetLastError());
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
WaitForSingleObject(hThread,
INFINITE);
if(GetExitCodeThread(hThread,
&exitCode))
{
printf("exit code = %d\n",
exitCode);
}
else
{
printf("GetExitCode failed\nGetLastError() = %d\n",
GetLastError());
}
CloseHandle(hThread);
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
现在,当我将一个shellcode(程序与上面的程序略有不同)注入一个进程时,我可以在进程资源管理器中看到我的shell代码如何开始运行以及受害者进程是他的父进程。在这里,我什么都看不见,但是,这是我第一次使用DLL。 但它仍然被加载,因为我无法删除dll文件,直到我杀死受害者进程。
另外,当我运行我的注射程序时,我可以看到它在5秒内无效,所以它就像跳过了printf一样。
在Windows 7 x64上执行此操作。我知道有些情况下CreateRemoteThread不能在Windows 7上运行,但我在我的shell代码注入中使用它并且它可以工作,我在这里使用相同的目标。
更新:更改我的DLL以调用ExitProcess(0);杀死受害者的过程,所以这一切都归结于我不知道如何打印的东西。
我怎样才能打印出来?
答案 0 :(得分:1)
您希望从DLL获取邮件,但使用printf
。你怎么看到DLL的printf
输出?您最好将信息写入文件。
#define LOG_FILE L"C:\\MyLogFile.txt"
void WriteLog(char* text)
{
HANDLE hfile = CreateFileW(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD written;
WriteFile(hfile, text, strlen(text), &written, NULL);
WriteFile(hfile, "\r\n", 2, &written, NULL);
CloseHandle(hfile);
}
void WriteLog(wchar_t* text)
{
HANDLE hfile = CreateFileW(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD written;
WriteFile(hfile, text, wcslen(text) * 2, &written, NULL);
WriteFile(hfile, L"\r\n", 4, &written, NULL);
CloseHandle(hfile);
}
用我的函数替换所有printf
次调用,看看实际发生了什么。顺便说一下,如果你的DLL中有线程,你可以每秒写一次日志,以确保你的代码有效。您也可以将时间添加到日志文件中。
我认为如果你有足够的权限将DLL注入进程,没有什么能阻止你。更改代码并告诉我日志文件中会发生什么。
祝你好运