我有一个我在一个进程中注入的DLL。它会搜索'file://',直到找到无效符号。几分钟后,它崩溃了主要过程。这是为什么?我怎么检查?我发现在CreateThread上堆栈大小较小时崩溃得更快,所以它可能以某种方式堆栈溢出,但我不是什么都不分配,只是一个结构。
BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 500, SampleFunction, 0, 0, NULL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
/* Return success */
return TRUE;
}
int Send(char* strDataToSend) {
HWND hWnd = FindWindow(NULL, "Test");
if (hWnd) {
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = (strlen(strDataToSend) + 1) * 2;
cpd.lpData = (PVOID)strDataToSend;
SendMessage(hWnd, WM_COPYDATA, (WPARAM) hWnd, (LPARAM)&cpd);
}
}
int isurl(char c) {
char* chars = "-._~:/?#[]@!$&'()*+,;=%";
for(int i = 0; i < strlen(chars); i++) {
if (chars[i] == c || isalnum(c)) {
return 1;
}
}
return 0;
}
TESTDLLMAPI void WINAPI SampleFunction(void) {
MessageBox(0,"LOADED !",0,0);
MEMORY_BASIC_INFORMATION info;
MEMORY_BASIC_INFORMATION* pinfo = &info;
while(1) {
int cnt = 0;
unsigned long addr = 0;
do {
ZeroMemory(&info, sizeof(info));
if (!VirtualQueryEx(GetCurrentProcess(), (LPCVOID) addr, pinfo, sizeof(info))) {
//MessageBox(0,"FAILED",0,0);
}
if (info.State == 0x1000) {
if (info.Protect == PAGE_READONLY || info.Protect == PAGE_READWRITE) {
__try {
if (info.RegionSize < 128) continue;
for(long i = 0; i < info.RegionSize - 10; i+=7) {
char* buff = info.BaseAddress;
if (buff[i] == 'f' && buff[i+1] == 'i' && buff[i+2] == 'l' && buff[i+3] == 'e' && buff[i+4] == ':' && buff[i+5] == '/' && buff[i+6] == '/') {
long start = i;
long end = start+7;
while(end < info.RegionSize - 10 && isurl(buff[end])) end++;
int len = end - start + 1;
char* test = (char*) calloc(len, 1);
//memcpy(test, buff+start, len);
int k = 0;
for (int j = start; j <= end; j++, k++) {
test[k] = buff[j];
}
Send(test);
free(test);
cnt++;
}
}
} __finally {}
}
}
addr = (unsigned long) info.BaseAddress + (unsigned long) info.RegionSize;
} while (addr != 0 && addr < 0x7FFF0000);
Sleep(1000);
}
答案 0 :(得分:3)
在Send函数中,您将缓冲区大小设置为字符串 x2 的长度,但是您将数据传递给指向char
的指针,该指针是一个字节。
还有一些提示:
info.RegionSize - 10
的结尾是500000,i = 499999怎么办?您将读取过去6个字节,这将导致崩溃。"file://"
不一定会在内存中的地址找到,其地址是7的倍数。如果您正在测试“123file:// ....”那么你'我会错过它,因为你会找到“123file”和“:// ....”VirtualQueryEx(GetCurrentProcess(), ...
是多余的。只需使用VirtualQuery
。0
。strstr
。cnt
应该服务的目的。CloseHandle
关闭句柄。我为你改写了SampleFunction
。我在旅途中写了它可能不会编译,但你应该得到一般的想法。
#include <windows.h>
BOOL IsPageReaable(PMEMORY_BASIC_INFORMATION pmbi)
{
if (pmbi->Protect & PAGE_GUARD)
return FALSE;
if (pmbi->Protect &
(PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_WRITECOPY | PAGE_READONLY
| PAGE_READWRITE | PAGE_WRITECOPY))
return TRUE;
return FALSE;
}
#define POLL_INTERVAL 1000
TESTDLLMAPI VOID WINAPI SampleFunction(VOID)
{
MEMORY_BASIC_INFO mbi;
ULONG_PTR ulAddress = GetModuleHandle(NULL); // base address
LPSTR lpszBase;
ZeroMemory(&mbi, sizeof(mbi));
if (!VirtualQuery(ulAddress, &mbi, sizeof(mbi)))
return;
if (!IsPageReadable(&mbi))
return;
lpszBase = info.BaseAddress;
for (;; Sleep(POLL_INTERVAL))
{
for (ULONG_PTR i = 0; i < info.RegionSize; i++)
{
int j;
LPSTR lpszBuffer;
if (strstr(&lpszBase[i], "file://") == NULL)
continue;
j = i + 1;
do {
j++;
} while (j < info.RegionSize && isurl(lpszBase[j])
lpszBuffer = (LPSTR)HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, sizeof(CHAR) * (j - i + 1));
if (lpszBuffer != NULL)
{
CopyMemory(lpszBuffer, &lpszBase[i], j - i);
Send(lpszBuffer);
HeapFree(GetProcessHeap(), 0, lpszbuffer);
}
}
}
}
答案 1 :(得分:0)
没有测试很难说出问题出在哪里但是你可以使用Ollydbg或Windbg调试你的进程来找到bug,这是你必须做的步骤:
1 - 附加到您的流程(例如使用Ollydbg表格File-&gt; Atach)
2 - 取决于注入方法,远程线程或SetWindowsHookEx:
远程线程(LoadLibrary):LoadLibrary上的断点然后使用olly打破新的dll加载并跟随dll的输入
SetWindowsHookEx:我没有对此进行测试,但我认为除了“LoadLibrary上的断点”部分之外,之前的方法也适用于此
3 - 然后调试以找到问题