JNZ77FCC9FB不能跳
f001B77FCC9EC8B4510MOVEAXEBP10001B77FCC9EF8B00MOVEAXEAXbuf1的堆的长度001B77FCC9F1F644C60501TESTBYTEPTREAX8ESI0501buf2的堆的flag是否含HEAP_ENTRY_BUSY001B77FCC9F68D3CC6LEAEDIEAX8ESIEDI指向buf2的起始地址001B77FCC9F97409JZ77FCCA04不含则跳(合并空闲堆?),这里要跳001B77FCC9FB8BC6MOVEAXESI001B77FCC9FD5FPOPEDI001B77FCC9FE5EPOPESI001B77FCC9FF5BPOPEBX001B77FCCA005DPOPEBP001B77FCCA01C21000RET0010001B77FCCA040FB70FMOVZXECXWORDPTREDIECX即buf2的堆的长度001B77FCCA0703C8ADDECXEAX加上buf1的堆的长度001B77FCCA0981F900FE0000CMPECX0000FE00是否大于0xfe00001B77FCCA0F77EAJA77FCC9FB大于则跳,这里不能跳001B77FCCA11807D1400CMPBYTEPTREBP1400001B77FCCA150F85FB210000JNZ77FCEC16001B77FCCA1B8A4705MOVALEDI05AL即buf2的flag001B77FCCA1E2410ANDAL10是否含HEAP_ENTRY_LAST_ENTRY001B77FCCA20A810TESTAL10001B77FCCA22884605MOVESI05AL将buf1的flag置为HEAP_ENTRY_LAST_ENTRY001B77FCCA25754BJNZ77FCCA72含则跳,这里不能跳001B77FCCA2757PUSHEDI001B77FCCA2853PUSHEBX001B77FCCA29E80CCBFBFFCALL77F8953A001B77FCCA2E8B4F0CMOVECXEDI0C将buf2的0x0c偏移给ECX001B77FCCA318B4708MOVEAXEDI08将buf2的0x08偏移给EAX001B77FCCA343BC1CMPEAXECX001B77FCCA368901MOVECXEAX这里发生异常001B77FCCA38894804MOVEAX04ECX方式三和方式二都是利用RtlFreeHeap函数,他们的分岔口在于关键点二的
001B77FCC8B80F858BF2FFFFJNZ77FCBB49方式二在这里要跳,方式三不能跳,从而进入下面的CALL关键点三发生异常时ECX0x22222222EAX0x11111111,这是我们能控制的。可见方式三的前提有三个1构造堆(buf2)的长度不能为02构造堆的上一个堆(buf1)和构造堆的长度相加不能大于0xfe00div8之后3)构造堆的flag不能包含HEAP_ENTRY_BUSY除了以上三种利用方式更有一种,和方式三差不多,不过是在freebuf2时发生异常,应该是由于在合并下
f一个堆时长度计算错误造成的,具体就不分析了,类似于li
ux下的堆溢出,不过wi
dows下不能将堆长度设为负数,造成一定的麻烦,sig
溢出之后的事情就不再说了。写这些主要为了分析总结一些东西,希望对初学者有帮助,不当之处请指正。更正一下,以上程式在
et平台下编译有效,VC60编译是不能溢出的。可能是两种编译器对malloc的实现方式不同。vc的编译器实现malloc的时候并没有真正调用RtlFreeHeap或RtlAllocHeap函数,造成溢出失败。改成HeapAlloc就能了
fr