使用代码注入在远程进程中执行函数
Executing function in remote process using code injection
我使用高级代码注入代码在远程进程上启动.dll。你可以从这里找到它是如何工作的/代码片段:
https://sourceforge.net/p/diagnostic/svn/HEAD/tree/src/RemoteInit.cpp我注意到,对于某些应用程序,这种方法不起作用——它会使主机应用程序崩溃。主要问题似乎是特殊类型的第三方软件,如ConEmuHk64.dll
,它通过提供自己的钩子函数来拦截kernel32.dll GetProcAddress
-之后,我得到这样的函数指针:
*((FARPROC*) &info.pfuncGetProcAddress) = GetProcAddress(hKernel32, "GetProcAddress");
但相反,我得到指向ConEmuHk64.dll中的函数的指针。
在我自己的进程中调用该函数是可以接受的,但是当试图在远程进程中做同样的事情时-它会崩溃,因为ConEmuHk64.dll
不一定在那里可用。
我已经找出了如何通过手动在DOS/NE其他标头中行走来自动探测该函数的正确地址的机制-这里是代码片段:
//
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party
// software and pointer to function returned to us is incorrect - then we try to locate function manually by
// ourselfes.
//
FARPROC GetProcAddress2( HMODULE hDll, char* funcName )
{
FARPROC p = GetProcAddress( hDll, funcName );
if( !p )
return NULL;
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll;
if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
return p;
IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew);
if ( pNtHeaders->Signature != IMAGE_NT_SIGNATURE )
return p;
IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader;
if( (char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode )
// Sounds like valid address.
return p;
// Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll)
IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress);
ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames);
ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions);
for ( DWORD i = 0; i < pExp->NumberOfNames; i++ )
{
char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]);
if ( strcmp( funcname, funcName ) == 0 )
{
void* p2 = (void*) ((BYTE*) hDll + funcaddr[i]);
return (FARPROC) p2;
}
} //for
return p;
} //GetProcAddress2
这似乎是为GetProcAddress
工作-我可以检测钩函数和覆盖它的行为。然而,这种方法并不是通用的。我已经尝试过类似的函数调用其他方法,例如FreeLibrary/AddDllDirectory/RemoveDllDirectory
-和那些函数指针指向dll边界- GetProcAddress
返回DOS头之前的地址。
我怀疑dll/代码大小范围的比较是不正确的:
if( (char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode )
但我不知道如何改进配方。
你能给我推荐一下如何完全修复这个问题吗-这样任何第三方软件都可以拦截任何功能,我也可以从它那里生存下来而不会崩溃?
函数指针解析是不正确的,如果使用"导出函数向前"(可以通过该术语搜索)。
一个合适的函数解析可以这样写:(你在上面看到的是从某个论坛复制粘贴的函数)
//
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party
// software and pointer to function returned to us is incorrect - then we try to locate function manually by
// ourselfes.
//
FARPROC GetProcAddress2( HMODULE hDll, char* funcName )
{
FARPROC p = GetProcAddress( hDll, funcName );
if( !p )
return NULL;
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll;
if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
return p;
IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew);
if ( pNtHeaders->Signature != IMAGE_NT_SIGNATURE )
return p;
IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader;
if( (char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode )
// Sounds like valid address.
return p;
// Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll)
IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress);
ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames);
ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions);
for ( DWORD i = 0; i < pExp->NumberOfNames; i++ )
{
char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]);
if ( strcmp( funcname, funcName ) == 0 )
{
ULONG addressOfFunction = funcaddr[i];
void* p2 = (void*) ((BYTE*) hDll + addressOfFunction);
if( addressOfFunction >= pDataDirectory->VirtualAddress && addressOfFunction < pDataDirectory->VirtualAddress + pDataDirectory->Size )
{
// "Exported function forward" - address of function can be found in another module.
// Actually for example AddDllDirectory is truly located in KernelBase.dll (alias api-ms-win-core-libraryloader-l1-1-0.dll ?)
char* dll_func = (char*) p2;
char* pdot = strchr(dll_func, '.');
if( !pdot ) pdot = dll_func + strlen( dll_func );
CStringA dllName(dll_func, (int)(pdot - dll_func));
dllName += ".dll";
HMODULE hDll2 = GetModuleHandleA(dllName);
if( hDll2 == NULL )
return p;
return GetProcAddress2( hDll2, pdot + 1 );
}
return (FARPROC) p2;
}
} //for
return p;
} //GetProcAddress2
除此之外,还可以在不同的地址加载。dll,但这不会发生在kernel32.dll或kernelbase.dll。
但是,如果.dll重基出现问题-解决的一种方法是使用EasyHook方法-可以位于这里:
https://github.com/EasyHook/EasyHook/blob/b8b2e37cfe1c269eea7042420bde305eb127c973/EasyHookDll/RemoteHook/thread.c- 如何在C++中将函数发送到另一个进程
- 是否有任何 C 函数或 API 来获取当前登录用户下运行的进程列表
- 使用参数调用远程进程中的函数(注入的 DLL)
- 在x64进程中调用x86 winapi函数
- 如何使用 WinDbg 查找"GetProcAddress"函数的进程名称
- C++,删除函数/迭代进程中定义的动态数组
- 为什么我不能用这个函数在Qt框架中打开另一个进程?
- Windows资源监视器使用哪些Win32函数来检测已终止进程的磁盘和网络活动
- 使用创建进程函数创建"dir"命令失败,错误代码为 2
- 我很困惑这个 execvp() 在此示例函数中如何处理,该函数使用 fork() 克隆进程
- Linux 守护进程 - 运行函数两次
- DBUS 代码在放置在守护进程内时崩溃,但在没有守护进程代码的独立独立 main() 函数中运行良好
- 从注入进程的 DLL 调用函数并更改指针函数的地址
- 如果构造函数中存在错误,请停止进程
- 从库中定义的进程调用静态函数
- 子进程的主函数
- 使用Spark调用进程外dll函数
- 如何使用MPI库仅为进程的子集调用(c++)函数
- exit()函数无法退出进程
- 从函数返回 boost::进程间内存映射文件