gpt4 book ai didi

c++ - 如何将 DLL 注入(inject) Delphi 程序

转载 作者:可可西里 更新时间:2023-11-01 09:34:58 26 4
gpt4 key购买 nike

我有一个遗留应用程序,其中包含一个包含我需要提取的数据的网格。

我没有该应用程序的代码,并且无法通过正常方式(例如以编程方式选择所有单元格并将它们复制到剪贴板)从中获取数据。

所以我决定按照“II. The CreateRemoteThread & LoadLibrary Technique”一节中的描述使用 DLL 注入(inject)

http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces

我的计划是

  1. 将 DLL 加载到遗留应用程序的地址空间。
  2. 让 DLL 从网格中读取数据并将它们写出(例如,通过命名管道)。

第一步是将 DLL 注入(inject)遗留应用程序的地址空间(上面的步骤 a))。

我为此编写了以下代码:

int  InjectDll            (HANDLE hProcess);

int _tmain(int argc, _TCHAR* argv[])
{
printf("DllInjector\n");

/**
* Find out PID of the legacy application (START)
*/
HWND windowHandle = FindWindowW(NULL, L"FORMSSSSS");
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);

DWORD delphiAppProcessId = *processID;
/**
* Find out PID of the legacy application (END)
*/

printf("Process ID of legacy app: %lu\n", delphiAppProcessId);

// Now we need the handle of the legacy app
HANDLE hProcess = OpenProcess(
PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, delphiAppProcessId);

if (hProcess != NULL)
{
printf("Found handle, ready for injection\n");
int result = InjectDll(hProcess);
CloseHandle( hProcess );
printf("Injection complete, result=%d\n", result);

}
else
{
printf("Handle not found\n");
}

system("pause");

return 0;
}

int InjectDll( HANDLE hProcess )
{
HANDLE hThread;
const char* const szLibPath = "D:\\mycompany\\SampleDll\\Debug\\SampleDll.dll";
void* pLibRemote = 0; // the address (in the remote process) where
// szLibPath will be copied to;
DWORD hLibModule = 0; // base adress of loaded module (==HMODULE);

HMODULE hKernel32 = ::GetModuleHandle(L"Kernel32");

// 1. Allocate memory in the remote process for szLibPath
// 2. Write szLibPath to the allocated memory
pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );
if( pLibRemote == NULL )
return false;
::WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath,sizeof(szLibPath),NULL);

// Load "LibSpy.dll" into the remote process
// (via CreateRemoteThread & LoadLibrary)
hThread = ::CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,"LoadLibraryA"),
pLibRemote, 0, NULL );
if( hThread == NULL )
goto JUMP;

::WaitForSingleObject( hThread, INFINITE );

// Get handle of loaded module
::GetExitCodeThread( hThread, &hLibModule );
::CloseHandle( hThread );

JUMP:
::VirtualFreeEx( hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE );
if( hLibModule == NULL ) // (1)
return false;


// Unload "LibSpy.dll" from the remote process
// (via CreateRemoteThread & FreeLibrary)
hThread = ::CreateRemoteThread( hProcess,
NULL, 0,
(LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,"FreeLibrary"),
(void*)hLibModule,
0, NULL );
if( hThread == NULL ) // failed to unload
return false;

::WaitForSingleObject( hThread, INFINITE );
::GetExitCodeThread( hThread, &hLibModule );
::CloseHandle( hThread );

// return value of remote FreeLibrary (=nonzero on success)
return hLibModule;
}

一些评论:

  1. 遗留程序的标题为“FORMSSSSS”。
  2. 示例 DLL 具有以下 DllMain 方法:

-

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved

{
OutputDebugStringA("DllMain called: ");
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugStringA("DLL_PROCESS_ATTACH\n");
case DLL_THREAD_ATTACH:
OutputDebugStringA("DLL_THREAD_ATTACH\n");
case DLL_THREAD_DETACH:
OutputDebugStringA("DLL_THREAD_DETACH\n");
case DLL_PROCESS_DETACH:
OutputDebugStringA("DLL_PROCESS_DETACH\n");
break;
}
return TRUE;
}

调用时,文本会写入应用程序的标准输出。


当我运行上面的程序(使用 _tmain 方法的程序)时,我希望看到文本

DllMain called: DLL_PROCESS_ATTACH

在控制台输出中(表示DLL注入(inject)成功)

但这并没有发生。


一个潜在的原因是遗留应用程序的PID确定不正确:

HWND windowHandle = FindWindowW(NULL, L"FORMSSSSS");
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);

DWORD delphiAppProcessId = *processID;

但 delphiAppProcessId 的值与任务管理器中显示的 PID 相同,因此我可以排除这个潜在的错误。


使用调试器我发现执行在注释 (1) 的行停止:

JUMP:   
::VirtualFreeEx( hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE );
if( hLibModule == NULL ) // (1)
return false;

为了将示例 DLL 注入(inject)到标题为“FORMSSSSS”的应用程序的地址空间中,我需要更改什么?

更新,2012 年 9 月 16 日:

我替换了所有出现的

大小(szLibPath)

按路径长度,其中

const int pathLength = strlen(szLibPath)+1;

现在,在

    ::WaitForSingleObject( hThread, INFINITE );
::GetExitCodeThread( hThread, &hLibModule );
::CloseHandle( hThread );

// return value of remote FreeLibrary (=nonzero on success)
return hLibModule;
}

hLibModule 非零,表示注入(inject)成功。

但是我在程序的输出中还是看不到示例DLL的日志输出。

更新,2012 年 9 月 16 日 (2):

当我

a) 在示例 DLL 的 DllMain 中添加对 AllocConsole() 的调用,b)重建它和c) 执行注入(inject)程序,

然后出现一个控制台窗口,它具有与 Delphi 应用程序相同的图标。

当我从 DllMain 函数中删除 AllocConsole 并执行注入(inject)应用程序时,控制台窗口没有出现。

所以注入(inject)可能真的有效。

最佳答案

我能看到的最大问题是 sizeof(szLibPath) 求值为指针的大小。请改用 strlen(szLibPath)+1

这肯定意味着您的注入(inject)将失败,因为 LoadLibraryA 接收的路径将被截断。可能还有其他问题,但这就是开始的地方。

关于c++ - 如何将 DLL 注入(inject) Delphi 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12437359/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com