挂是VMP3.X加密的 把通信包加密钥和发到服务器取随机码固定后就可做服务端
关于修改VMP那个偏移值 是不同环境不同的 具体要看调试环境并不通用
计算返回地址那太烦人 如果HOOK位很多 还是写DLL好一点
代码是aardio 实现
hook=function(){
var prcs=process("C:\Users\Administrator\Desktop\ABC.exe",,{suspended=true})
oep=0xa0791b
oepnum=prcs.readNumber(oep,"INT") //读OEP头
prcs.writeNumber(oep,0xfeeb,"WORD")//硬断点
prcs.resume()
sleep(10)
prcs.suspend()
prcs.writeNumber(oep,oepnum,"INT")//eip已停在OEP 把OEP头还原
while(true){
prcs.resume()
sleep(1)
prcs.suspend()
ker32=prcs.getModuleBaseAddress("kernel32.dll")//等系统加载再取基址
if ker32 != null {
ker32=ker32 0x1165c
advapi=prcs.getModuleBaseAddress("advapi32.dll")
ws2_32=prcs.getModuleBaseAddress("ws2_32.dll")
if ws2_32 != null {
prcs.writeNumber(ker32,0xfeeb,"WORD")//硬断
break ;
}
}
}
prcs.resume()
sleep(10)
prcs.suspend()
//关掉VMP3.X反调试和保护开关
injectCode1=
'\x81\x3c\x24\x65\xa5\xae\x00'//cmp dword[esp],0xaea565
'\x75\x0B'//jne 0b
// '\x60' //pushad
'\xc7\x84\x24\x8c\x04\x00\x00\x00\x00\x00\x00' //mov dword [esp 48c],0 //关闭VMP功能标志位
// '\x61'//popad
// '\xeb\xfe'
'\x81\x3c\x24\xe5\xed\xcc\x76'//cmp dword[esp], advapi32.dll 2dde5
'\x75\x0E'//jne 0E
'\x8b\x1d\x11\xde\x50\x00' //mov ebx,dword[50de11] 读取标志位地址
'\xc7\x03\x01\x00\x00\x00' //mov dword [ebx],0x1
'\x33\xdb' //xor ebx,ebx
'\x8b\xff' //mov edi,edi
'\x55'//push ebp
'\x8b\xec' //mov ebp,esp
'\x5d' //pop ebp
'\xff\x25\xdc\x0b\x0e\x76' //jmp dword [760E0BDC]
//hook send明文位置1
injectCode2 =
'\x8b\x3f'//mov edi,dword[edi]
'\x81\x3f\x7b\x22\x73\x74'//cmp dwrod [edi],0x7473227b 判断明文包是不是取随机码
'\x74\x0d'//je 0d
'\x6a\x1c'//push 1c
'\x68\xe1\xdd\x50\x00'//push 50dde1
'\xff\x25\xdd\xdd\x50\x00' //jmp 返回
'\x50' //push eax 长度
'\x57' //push edi 明文包指针
'\x8b\xcb' //mov ecx,ebx
'\xff\x25\xdd\xdd\x50\x00'//jmp [50dddd]
//hook connect 修改Ip地址
injectCode3=
'\x36\xc7\x40\x04\x0a\x00\xa8\xc0' //mov dword [eax 4],ip 修改ip地址 192.168.0.10 '\xeb\xfe'
'\x8b\xff'
'\x55'
'\x8b\xec'
'\x60' //pushad
'\x8b\x1d\x15\xde\x50\x00' //mov ebx,dword[50de15] 读取标志位地址
'\xc7\x03\x01\x00\x00\x00' //mov dword [ebx],0x1 写标志位2
'\x33\xdb' //xor ebx,ebx
'\x61'//popad
'\xff\x25\x0d\xde\x50\x00' //jmp [50de0d]
//固定随机码
injectCode4=
'\x8B\x44\x24\x04' //mov eax,dword[esp 4] 数据指针
'\x8B\x5C\x24\x08' //mov ebx,dword[esp 8] 长度
'\xB9\x00\x00\x00\x00' //mov ecx,0
'\x3B\xD9' //cmp ebx,ecx
'\x74\x07' //je 07
'\xC6\x04\x08\x11' //mov byte,[eax ecx],0x11
'\x41' //inc ecx
'\xEB\xF5'//jmp f5
'\xC2\x08\x00'//retn 0x8
addrInject=prcs.malloc(0x1000)
thread.command.print(tostring(addrInject,16),"区段基址")
addDate1=addrInject
addDate2=addrInject (#injectCode1)
addDate3=addrInject (#injectCode1) (#injectCode2)
addDate4=addrInject (#injectCode1) (#injectCode2) (#injectCode3)
addrHook1=ker32 //Localalloc
addrHook2=0x0041e8b5 //send明文位
addrHook3=ws2_32 0x68f5 //connect
addrHook4=advapi 0x192d //systemfunction036
offsetJmpBack1 = addrInject - (addrHook1 5) /计算HOOK1的偏移值
offsetJmpBack2 = addDate2 - (addrHook2 5) //计算HOOK2的偏移值
offsetJmpBack3 = addDate3 - (addrHook3 5) //计算HOOK3的偏移值
//offsetJmpBack4 = addDate4 - (addrHook4 5)
//thread.command.print(#injectCode1,"代码1长度")
//thread.command.print(offsetJmpBack2,"代码1")
//offsetJmpBack2 = addrInject #injectCode1 -(addrHook2 5)
prcs.writeString(addDate1,injectCode1) //写入HOOK内容
prcs.writeString(addDate2,injectCode2)
prcs.writeString(addDate3,injectCode3)
prcs.writeString(addDate4,injectCode4)
prcs.writeString(addrHook1,'\xE9') //写入目标进程HOOK1位置JMP
prcs.writeNumber(addrHook1 1,offsetJmpBack1,"INT") //写入HOOK1后4位地址跳到修改的代码
prcs.writeString(addrHook3,'\xE9')
prcs.writeNumber(addrHook3 1,offsetJmpBack3,"INT")
//-------------------------数据区--------------------
//在目标进程找块空的地方用来存放数据
prcs.writeString(0x50dde1,'{"stype":3,"rand":522574520,"r":10}') //写入明文包
prcs.writeNumber(0x50dddd,0x41e8bb,"INT") //写入HOOK2返回数据 这样方式就不用计算返回地址那么麻烦
prcs.writeNumber(0x50de0d,ws2_32 0x68fa,"INT") //connect 返回地址
prcs.writeNumber(0x50de11,addrInject 0xffc,"INT") //写入标志位1地址
prcs.writeNumber(0x50de15,addrInject 0xff8,"INT") //写入connect标志位地址
prcs.writeString(0x50de19,"192.168.0.10")
while(true){
prcs.resume()
sleep(1)
prcs.suspend()
var str=prcs.readNumber(addrInject 0xffc,"BYTE")//判断标志位1
if str == 0x1 {
thread.command.print("找到第一个标志位")
prcs.writeString(addrHook2,'\xE9') //写入HOOK2位置E9
prcs.writeNumber(addrHook2 1,offsetJmpBack2,"INT") //写入HOOK2后4位地址
break ;
}
}
while(true){
prcs.resume()
sleep(1)
prcs.suspend()
var str1=prcs.readNumber(addrInject 0xff8,"BYTE")//判断标志位2
if str1 == 0x1 {
thread.command.print("找到第二个标志位")
prcs.writeString(addrHook4,injectCode4) //connect后才改随机码 太早改会遇到CRC校验
break ;
}
}
prcs.resume()
————————————————
版权声明:本文为CSDN博主「steak123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/steak123/article/details/120413882
主题数 170 | 今日评论 0 | 今日主题 0 |