WINDOWS黑客根蒂根基(5):哄骗内存来进行获取策画成果
添加时间:2013-6-23 点击量:
在前面的注入代码的章节中,我们哄骗了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来将数据放到内存的某个处所
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》
在前面的注入代码的章节中,我们哄骗了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来将数据放到内存的某个处所
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》