条件跳转/控制流
这部分会涉及到高级语言中FOR,WHLIE 和 DO/WHILE 语句。
NOP 指令只是填充材料,用它来取代一些有用的地方。
通常如果 ECX 空闲的话我会用它来配合 LOOP 指令只用,这都得看情况。
循环 2 次
另一种循环两次的方法是如果你所有的寄存器都用完了,你可以使用进位标志。我们首先清空它(如果还没有的话),将该标志保存到栈中,执行我们的代码,重新保存标志符,填充,然后再循环。
循环 3 次
对于PF,将一个寄存器设置为0,并inc 直到PF=1.
对于SF,将一个寄存器设置为0,并增加 43 到 63 的一个数,直到SF=1。
对于ZF,将一个寄存器设置为0,并增加 85 知道ZF=1.
你可能会说,我们也可以简单的讲 EAX 设置为3,然后 dec 直到0,这也是正确的。
如果可以用ECX,我们可以用LOOP
当 ECX 空闲,就用 LOOP。
如果我们不能用 ECX,将 AL 设置为 -1 然后用 sub,相比于第 2 个例子,这样能够为我们节省一个字节。如果你喜欢用加法,你也可以将 AL 设置为 1。
循环 4 次
这个会比较简单,因为对于ZF,256能被4整除,对于SF,256能被128整除。
你可以继续这样做,但是从上面的例子中你应该学会自己写。
关于实现涉及条件跳转的控制流的最后一部分是使用相对偏移量。比如说,现在情况是这样,有一个其他函数的返回值,你想伪造一个函数来混淆代码,让分析代码变得更困难。这是很基础的。
虽然这里只测试了TRUE或FALSE,但如果要测试-1或小于0的有符号值也很简单啊。
字符转换
在很多情况下你会想要把一串小写字母转换为大写以及相反操作,或者实现unicode到ansi的转换。这里只是展示如何转换拉丁字母表。
大/小写转换
转换大小写不过是开关切换键的事。观察下面的字母以及它们的二进制值。
a = 01100001 A = 01000001
b = 01100010 B = 01000010
c = 01100011 C = 01000011
对于小写,第五位是1(我是从零开始算的)。
如果你想要一串字符串全是小写或全是大写,用XOR。
// flip the case "\x34\x20" /* xor al, 0x20 */
如果你想将字符串都变成小写但又不想每一位都比较,用OR。
// convert to lowercase "\x0c\x20" /* or al, 0x20 */
至于要转换成大写,将它和0xDF进行 and,这样第五位就会变为0. 这里有个问题是,如果是数字或者该字母没有对应的小写字母的话,这个方法将失效。
// convert to uppercase "\x24\xdf" /* and al, 0xdf */
当然你也可以用BTS把它设置为小写,但是这需要占用更多字节。
// set to lowercase "\x0f\xba\xe8\x05" /* bts eax, 0x5 */
或者如果你只想改变那个字母,用BTR。
// flip case "\x0f\xba\xf0\x05" /* btr eax, 0x5 */
如果你的那串字符串里有数字或者其他字符会发生什么呢?有一次我在shellcode里用了转化小写而不是转换为大写,因为大写需要条件跳转而当时我并不想跳转。
拿metasploit的代码 block_api.asm 来举个例子。
将字符串转换为小写,你可以用下面的代码。记住,这里是从InLoadOrderLinks 读取DLL的相关信息,跟Metasploit 读的不一样。
你肯定不能直接把这段代码插入到原来的metasploit代码中去,因为生成的hash值完全不一样。这只是给你介绍一直方法。
如果你用OR来设置数字0~9的第五位,它们不会有任何改变,因为它们的第五位本来就是1 啊。
同样的,对于用来做分开模块名和后缀的“.”也一样不会改变。比如,用OR可以将KERNEL32.DLL 变成 kernel32.dll 而不需要任何条件跳转。
但是如果是用SUB指令来讲其转换为大写,你需要条件跳转。
Ansi 和 Unicode
好吧,这并不完全是unicode转换因为我们只用到拉丁字母表。Unicode字符串以两个null字节作为结束标志,所以一旦遇到null应该停止。
致谢
有很多人通过分享他们的知识和想法帮我间接完成了这篇博文。文章中的代码借鉴了这些人的想法:
drizz,
r!sc, d0ris, jb, Z0MBiE, WiteG, Vecna, Mental Driller, GriYo, JPanic,
Qkumba/Peter Ferrie, Jacky Qwerty, Super, hh86, benny 还有一些我忘了的。
本文由 看雪翻译小组 lumou 编译,来源 modexp
如果你喜欢的话,不要忘记点个赞哦!