前段时间写的代码,写完后一运行就出错,又因为手头有点事,就放在那了.今天中午没事拿出来和"雪"牛一起看了看,终于能跑起来了.这种被ken戏称称为"吸星大法"的技术,确实没啥新意,只当练手吧.顺便温习下IAT HOOK和PE结构.高手飘过!
大体说下思路:首先利用远程线程注入到系统的explorer.exe进程,注入后利用IAT HOOK,勾住explorer.exe的CreateProcessA,因为应用程序都是这个桌面进程拉起来的.所以后面创建的进程,都会走进我们挂钩后的函数.在我们的函数中做下过滤,根据进程名判断是否是我们感兴趣的进程.如果是,以CREATE_SUSPENDED标志创建进程,此时该进程虽然被创建但已被挂起.这时,我们可以将进程对应的可执行文件映射进内存,根据PE结构知道该进程的EP,然后修改EP处的代码.我这里选择的方式是,从EP开始搜索第一个call xxxx,然后修改xxxx处的地址,直接跳转到我们的代码处(当然必须先将我们的代码写入目标进程中),执行完我们的代码,再JMP到call对应的xxxx处.至于我们的代码中要干什么,想干什么就干什么了,我这里只是向进程load了一个dll.有人可能会问,这样不是闲着蛋疼,没事找事,直接为目标进程创建一个LoadlibraryA的远程线程不就load一个dll了,问题是有些进程自己做了保护,程序运行起来后,就不那么轻易让你注入了.废话不多说,直接上代码吧!
代码1:向系统的explorer.exe进程注入DLL
这段代码没什么好解释的,就是在系统进程快照中查找名叫explorer.exe的进程id,然后通过OpenProcess将进程映射到本进程的句柄表中,再远程分配空间,写内存,创建远程线程.
void main()
{
char lpDllName[100] = {0};
GetCurrentDirectory( 100, lpDllName );
strcat( lpDllName, "\\InjectProcessDll.dll" );
cout<<"Dll当前路径:"<<lpDllName<<endl;
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hSnapshot == NULL )
{
cout<<"Create Snapshot false."<<endl;
cin.get();
return;
}
PROCESSENTRY32 stProcessEntry32 = {0};
stProcessEntry32.dwSize = sizeof(PROCESSENTRY32);
Process32First( hSnapshot, &stProcessEntry32 );
bool bFind = false;
do
{
if( strncmp( stProcessEntry32.szExeFile, "explorer.exe", strlen("explorer.exe") ) == 0 )
{
bFind = true;
break;
}
}while( Process32Next( hSnapshot, &stProcessEntry32 ) );
CloseHandle( hSnapshot );
if( !bFind )
{
cout<<"查找explorer进程失败."<<endl;
cin.get();
return;
}
DWORD dwPId = stProcessEntry32.th32ProcessID;
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwPId );
if( hProcess == NULL )
{
cout<<"打开explorer进程失败."<<endl;
cin.get();
return;
}
LPVOID lpDllNameAddr = VirtualAllocEx( hProcess, NULL, strlen(lpDllName)+1, MEM_COMMIT, PAGE_READWRITE );
if( lpDllNameAddr == NULL )
{
cout<<"explorer进程中申请内存失败."<<endl;
CloseHandle(hProcess);
cin.get();
return;
}
cout<<"在目标进程:"<<stProcessEntry32.szExeFile<<"中申请的空间地址:"<<hex<<lpDllNameAddr<<endl;
DWORD dwRes = 0;
bool bRet = WriteProcessMemory( hProcess, lpDllNameAddr, lpDllName, strlen(lpDllName), &dwRes );
if( !bRet )
{
cout<<"explorer进程写信息失败."<<endl;
VirtualFreeEx( hProcess, lpDllNameAddr, strlen(lpDllName)+1, MEM_DECOMMIT );
CloseHandle(hProcess);
cin.get();
return;
}
HMODULE hModuleKernel32 = GetModuleHandle("kernel32.dll");
LPTHREAD_START_ROUTINE lpLoadLibraryAddr = (LPTHREAD_START_ROUTINE)GetProcAddress( hModuleKernel32, "LoadLibraryA" );
if( lpLoadLibraryAddr != NULL )
{
cout<<"获得函数地址:"<<hex<<lpLoadLibraryAddr<<endl;
HANDLE hRemote = CreateRemoteThread( hProcess, NULL, 0, lpLoadLibraryAddr, lpDllNameAddr, 0, NULL );
if( hRemote != NULL )
{
cout<<"创建远程线程成功,句柄:"<<hex<<hRemote<<endl;
WaitForSingleObject( hRemote, INFINITE );
CloseHandle( hRemote );
cout<<"远程线程运行结束"<<endl;
cin.get();
}
else
cout<<"创建远程线程失败."<<endl;
}
else
cout<<"获取LoadLibrary地址失败"<<endl;
VirtualFreeEx( hProcess, lpDllNameAddr, strlen(lpDllName)+1, MEM_DECOMMIT );
CloseHandle(hProcess);
cin.get();
return;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)