前面分享了两篇如何用C语言写壳程序和加壳程序,但是没有分享这个技术如何应用,今天就拿WinXP系统下的NOTEPAD.EXE 文件和Win7系统下的NOTEPAD.EXE 文件来练练ExeShellCode这把“刀”怎么使。就来拦截NOTEPAD.EXE 文件把文本数据写到文件吧,这个应用属于代码感染的范畴,UpExeShellCode.exe没有加入反汇编引擎所以对于编译地址和指令长度没有加以检查,需要人为设置,如果本代码有人用于病毒感染,诉与本人无关,我这里目的只是演示如何应用用C语言写壳程序而已。实现步骤: 1.先找到NOTEPAD.EXE 文件把文本数据写到文件的汇编代码地址,因为XP系统的NOTEPAD.EXE 是没有重定位的,所以我们调试的NOTEPAD.EXE模块地址就是它的编译地址。先在kernel32.dll的WriteFile函数下断,然后在记事本里随便写一些东西,执行保存或另存为菜单,当在kernel32.dll的WriteFile函数断下后 如图: 记下返回地址为0x01004C30,这个地址既是运行地址也是编译地址。 2.考察 0x01004C30 这个编译地址附近的汇编指令,需要在调用kernel32.dll的WriteFile函数前下钩子,而且要避开跳转指令,因为被下钩子的地方机器码会被修改,所以原来的机器码是需要备份的,但是要注意备份是需要CPU指令也就是汇编指令对齐的,不能备份不完整的汇编指令,同时备份的所有指令的操作数是不能有被重定位的。所以这一步要决定2个数据:被下钩子的编译地址和指令长度。如图: 这里选择编译地址为:0x01004C1E 指令长度选择:12,当然也可以选择5、6和9。其他的可就不行了。3.在启动 UpExeShellCode.exe 里把前面选择的编译地址(0x01004C1E)和指令长度(12)正确填写。 这两个数据会在UpShellCodeClass.cpp里 对 InlineShell2 函数的调用参数就需要前面的 0x01004C1E 和 12 这两个数。对于 InlineShell2 函数的调用,个人觉得程序有左出右入、右出左入的感觉,程序由加壳的正常程序进入到处于堆内存的 InlineShell2 函数,而处于堆内存的 InlineShell2 函数由会调用加壳的正常程序提供的地址转换函数。而在壳源的 InlineShell2 函数实现了对NOTEPAD.EXE 文件的编译地址0x01004C1E 进行inline Hook。 InlineShell2 函数代码并不多,但是不容易让人理解,执行了好几种地址转换,在 PeAddressFunc.cpp 文件里都有实现,代码里面我都有注释,这里就不再解释。跟XP系统的NOTEPAD.EXE 文件差不多,Win7的NOTEPAD.EXE 文件,我们获取的 0x00837B27 不再是编译地址了,它是只能当运行地址。我们这里就选中 0x00837B15 这个运行地址下钩子, 我们还需要手动要计算出 0x00837B15 的编译地址:0x00837B15 - 0x00830000(当前加载基地址) = 0x7B15 (这个就是RVA) ,把这个 RVA加上预加载地址 ImageBase 0x01000000 就是编译地址:0x01007B15 ,指令长度跟修改XP系统的记事本一样选12。 如图:只要 下钩子的编译地址和指令长度选择正确,这个UpExeShellCode.exe 还可以对其他EXE文件下钩子的。写外挂的大牛们,看完这些分享的代码,是不是觉得用C语言(用少量的内镶汇编)写外挂会比完全用汇编来的容易、更不容易出错?先声明:我可从没有干过写外挂的活,我只是业余者!对于分享如何用C语言写ShellCode,这是我的最后一次分享,今后希望在看雪上可以看到更多的人分享创意的代码,我静待学习。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)