这部分会涉及到高级语言中FOR,WHLIE 和 DO/WHILE 语句。
NOP 指令只是填充材料,用它来取代一些有用的地方。
通常如果 ECX 空闲的话我会用它来配合 LOOP 指令只用,这都得看情况。
另一种循环两次的方法是如果你所有的寄存器都用完了,你可以使用进位标志。我们首先清空它(如果还没有的话),将该标志保存到栈中,执行我们的代码,重新保存标志符,填充,然后再循环。
对于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。
这个会比较简单,因为对于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。
如果你想将字符串都变成小写但又不想每一位都比较,用OR。
至于要转换成大写,将它和0xDF进行 and,这样第五位就会变为0. 这里有个问题是,如果是数字或者该字母没有对应的小写字母的话,这个方法将失效。
当然你也可以用BTS把它设置为小写,但是这需要占用更多字节。
或者如果你只想改变那个字母,用BTR。