注入的 dll 会使所有者进程崩溃。为什么?
我有一个在进程中注入的 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);
}
I have a dll that I injected in a process. It searches 'file://' until it finds invalid symbol. After a few mins it crashes the main process. Why is that? How can I check? I found that with smaller stack size on CreateThread it crashes faster, so it can be somehow stack overflow, but I'm not allocating nothing, but a single struct.
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 = "-._~:/?#[]@!amp;'()*+,;=%";
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 Send 函数中,您将缓冲区大小设置为字符串 x2 的长度,但您将指针中的数据传递给
char
(一个字节)。还有一些提示:
info.RegionSize - 10
的末尾为 500000,且 i = 499999,会怎样?您将读取超过 6 个字节,这将导致崩溃。“file://”
不一定会在内存中地址为 7 倍数的位置找到。如果您碰巧正在测试“123file://” ...." 那么您就会错过它,因为您会找到“123file”和“://....”VirtualQueryEx(GetCurrentProcess(), ...
是多余的。只需使用 < code>VirtualQuery0
strstr
。cnt
的用途是什么 您在 DllMain 中创建了一个线程,CloseHandle
关闭它们。您的
SampleFunction
是我在旅途中编写的,它可能无法编译,但您应该了解总体思路。In your Send function you're setting the buffer size to the length of the string x2 but you are passing the data in a pointer to a
char
, which is one byte.A few more tips:
info.RegionSize - 10
is at 500000, and i = 499999? You'll read 6 bytes past which will cause a crash."file://"
isn't necessarily going to be found at a place in memory with an address that is a multiple of 7. If you happen to be testing "123file://...." then you'll simply miss it, because you'll find "123file" and "://...."VirtualQueryEx(GetCurrentProcess(), ...
is redundant. Just useVirtualQuery
.0
.strstr
.cnt
is supposed to serve.CloseHandle
once you're no longer going to use them (in this case, i.e. right after you've created it)I rewrote your
SampleFunction
for you. I wrote the on the go and it probably won't compile, but you should get the general idea.未经测试,很难说问题发生在哪里,但您可以使用 Ollydbg 或 Windbg 调试进程来查找错误,这是您必须执行的步骤:
1 - 附加到您的进程(例如使用 Ollydbg 形式 File->Atach)
2 - 取决于注入方法、远程线程或 SetWindowsHookEx :
远程线程(LoadLibrary):在 LoadLibrary 上设置断点,然后使用 olly 中断新的 dll 加载并跟踪条目dll
SetWindowsHookEx:我没有测试这个,但我认为以前的方法在这里也适用,除了' LoadLibrary 上的断点部分
3 - 然后调试以发现问题
without test it's hard to say where problem occurd but you can debug your process with Ollydbg or Windbg to find the bug, here is step you must do:
1 - Attach to your process (for example with Ollydbg form File->Atach)
2 - Depend on injection method, remote thread or SetWindowsHookEx :
remote thread(LoadLibrary): breakpoint on LoadLibrary then use olly to break on new dll load and follow entry of dll
SetWindowsHookEx: I don't test this but I think previous ways work here too except 'breakpoint on LoadLibrary' part
3 - Then debug to find problem