WINDOWS黑客基础(5):利用内存来进行获取计算结果
在前面的注入代码的章节中,我们利用了VirtualAllocEx来在对方的进程开辟了一块内存,并且将代码复制进对方进程的内存里面,从而执行那段内存的代码,但是这里有一个问题,就是代码不是执行在我们进程内的,所以我们无法像在本进程编程那样直接利用返回值或者传入指针来获取计算结果,这个时候我们可能需要到很多通讯手段,但是这样将会让我们的注入代码变得非常复杂,所以我自己想了一个方法,就是利用VirtualAllocEx开辟的内存区域来进行通讯
整体的步骤是这样的:
1.在对方的内存开始一块内存,
2.复制代码进去
3.根据代码计算出我们的结果应该放在哪里,比如我们申请了100字节的内存,其中50字节是代码,那么我们应该想办法把我们的结果放在50字节以后的地方
4.假设根据上面的步骤,我们的结果放在了内存偏移地址为60的地方,那么我们可以将指向这快内存的指针向后移动60个字节,那么这个就是我们存放结果的地方
上面的这种方法当然只是适合存放小数据的,如果有大的数据需要传出来,我们还是需要其他的手段,比如开辟共享内存,利用SOCKET等手段
有人也会说专门开辟一块内存存放数据,这样的话我们就可以把内存放在这个地方,而不是把代码跟计算结果混淆,但是要知道,因为内存映射的原因,指向同一块物理内存的不同进程对应的虚拟内存地址不一定是一样的,也就是说,我们把代码从A进程注入了B进程,此时我们的在A进程向B进程VirtualAllocEx了一块内存,在A进程的地址是1000,我们的代码也是把数据写入到虚拟内存地址1000的,但是这段代码是在B进程执行的,那么B进程虚拟内存地址1000是什么东西??没人会知道
在这个方法中还有一个比较重要的就是取得当前代码运行的地址,本来寄存器是有EIP这个寄存器可以让我们看到究竟程序运行到了哪个内存地址的代码,但是我们在编译器中无法使用EIP,也无法读取,所以我们使用另外一种方法,就是call 命令,CPU在执行CALL命令后,会把我们的下一段代码的地址push到栈里面,这个时候我们可以利用这样获取下一段代码的地址
call Next
Next:pop eax
这样,eax里面就是我们next:pop eax这段代码的地址了
但是后来我想了下,这种方法不是很安全,原因跟上面说的那个一样,指向同一块物理内存的不同进程对应的虚拟地址不一定是一样的,而编译器在给我们编译cal next的时候已经把地址写死了,我试验了下,两个不同进程的虚拟内存地址是一样的,但是我没找到肯定的说明,所以没办法确定,因此这种方法不是很安全
我本来还想用另外一种方法就是CONTEXT,windows下有GetThreadContxt可以获取当前线程的context,但是这个方法也没办法拿到正确的EIP,因为如果一个线程没有停止运行,EIP会变,但是我想了下,在我们debug的时候有办法拿到函数调用栈,那么应该也有办法获取函数的调用栈,这个办法也许虽然不能拿到EIP,但是却可以拿到线程一些函数的地址,后面也可以通过函数地址+offset来将数据放到内存的某个地方