| 本帖最后由 十二 于 2011-5-8 10:10 编辑 
 在windows中进程是相互独立的,(详见本版ollydbg新手教程)。不过windows提供一种跨进程访问内部资源的方法,借助这种方式可以使得动态修改已经被创建的进程。
 
 如果想修改一个远程进程内部的数据,或者得到某个远程进程的内部资源。则需要先用OpenProcess函数打开远程进程。
 
 OpenProcess 原型如下:
 
 HANDLE WINAPI OpenProcess(  __in  DWORD dwDesiredAccess,  __in  BOOL bInheritHandle,  __in  DWORD dwProcessId);
 
 dwDesiredAccess 对进程的安全描述
 bInheritHandle 如果创建进程是否继承返回的进程句柄
 dwProcessId 进程ID也就是常说的PID
 
 dwDesiredAccess 如果没有特殊要求请设置成PROCESS_ALL_ACCESS,以便得到远程进程的所有访问权限。
 
 OpenProcess函数将返回一个远程进程的句柄,该句柄继承PROCESS_ALL_ACCESS的所有属性。
 妥善保管好OpenProcess返回的进程句柄,因为以下的操作都会用到OpenProcess返回的进程句柄作为参数。
 
 接下来可以用VirtualAllocEx来在远程进程中创建一个内存空间,以便存放Shell Code,原型我就不贴了。
 函数将放回创建好内存的首地址,然后就可以用 WriteProcessMemory和ReadProcessMemory来远程写入和读取数据了。如果碰到不能写的页面可以用VirtualProtectEx 去掉页保护。
 
 接下来你有两个选择,一个是编写好DLL然后使用CreateRemoteThread远程创建一个线程来实现你得DLL。
 
 这篇渣文说的是Shell Code自然重点不在CreateRemoteThread上。
 
 下面我说Shell Code的注入方法。
 
 这种方法很麻烦,但是有一定的研究价值。
 
 在自己的进程内部当然怎么XX都可以,但是在远程就不能随心所欲了。
 
 ①得到远程Kernel32.dll的基址,Kernel32.dll的DLL Characteristics为 0140 载入的时候将自动处理重定位信息。大部分的时候
 Kernel32会加载到预订的imagebase中处理重定位后得到一个固定的地址,但是你不能排除,kernel32将被重定位到其他地址。
 
 mov eax, [fs:30h] 得到PEB
 mov eax, [eax+0ch] 得到PEB_LDR_DATA结构
 mov eax, [eax+1ch] 此时eax中的值是ntdll的线性地址
 mov eax, [eax]
 mov eax, [eax]
 mov eax, [eax+8] 此时eax中的值便是kernel32的基址
 
 得到kernel32的远程基址能干什么?kernel32的基址相当于模块的句柄这样就可以用GetProcAddress函数来得到远程任意函数的地址。
 
 2、必须使用WriteProcessMemory将Code写入到远程然后执行,别期望用JMP在两个进程之间互相跳没有这种好事,进程还是独立的OpenProcess并不提供进程合并功能。
 3、如果不调用 CreateRemoteThread 怎么执行你的CODE。获得kernel32的基址后就等于拥有了目标进程所有的函数地址。你需要做的就是找一个远程进程必将访问的函数HOOK函数的前6个字节使其跳到你VirtualAllocEx申请的CODE区。
 但是JMP和CALL是报废的为什么报废后面说,你可以用PUSH 和 RET在堆栈里构建一个返回。然后记得回复原来的函数入口。
 当然你也可以不这么做,远程CreateThread也行。反正你都得到了远程的内存空间了,但是相当麻烦。
 
 4、很重要的一点:
 WriteProcessMemory的时候JMP和CALL将全部报废,CALL和JMP的HEX值不是绝对的。CALL后的地址计算方式是E8 指令所在地址+下个指令在内存中的偏移后的HEX值,反则HEX也是不同的。
 
 有变通方法有两种一种是用kernel32的基址和GetProcAddress进行计算然后得到正确的HEX。另一种就kernel32的基址和GetProcAddress得到地址然后 用call [00000000],WriteProcessMemory的时候也要注意毕竟你操作的是远程地址,需要根据VirtualAllocEx返回的地址进行一系列的修正。才能保证你得Code成功运行。
 
 以下进入口胡部分:
 
 如果把自身EXE映射到宿主应该是个不错的方法LoadLibrary也能载入EXE。但是前提是EXE的imagebase不能被占用,因为EXE大部分都没重定位。或者你再编写的时候就找一个非常稀有的imagebase然后LoadLibrary到宿主。
 
 手指坏了打字好蛋疼
  
 
 
 
 
 
 
 
 
 
 
 
 |