首页
社区
课程
招聘
[原创]看雪.深信服 2021 KCTF 春季赛 第六题 寻回宝剑
发表于: 2021-5-19 00:15 7377

[原创]看雪.深信服 2021 KCTF 春季赛 第六题 寻回宝剑

2021-5-19 00:15
7377

IDA打开,发现代码加了混淆,但规律性很强。

解混淆是一个迭代的过程:

首先注意到一个反复出现的代码片段:

这段代码的效果等同于push一个地址,其值等于pop rax指令的地址异或上xor指令里的常量,是一个能够静态计算出来的确定的值。(注意文件头的IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE没有置位,程序没有开启动态基址,因此xor运算后的地址才有效)
这样的代码片段可以统一替换为VIRTUAL push XXXXYYYY(VIRTUAL前缀是人为加的,为了区分程序里真实的push指令)

替换之后,程序里出现大量的

等同于一条无条件跳转指令VIRTUAL jmp XXXXYYYY

对同一个寄存器连续的push和pop,可以直接去除

VIRTUAL jmp连接的代码块重新排序让它们顺序连在一起,从而省略掉无用的VIRTUAL jmp指令。在完成这一步后,重做第3步。

出现了一个新的模式(这个模式只有在前4步都做完之后才能看出来,因为这些指令在源程序中并不是连续的)

与第1步类似,整个片段等价为push一个常量。可以将整个片段替换为VIRTUAL push XXXXYYYY,然后重做第2步

反复迭代以上的步骤,重点是指令块的重新排序(第4步),每次重新排序后再次搜索第1、2、3、5步的代码模式做替换。直到代码不再能化简,打印输出即可。

由于混淆模式非常固定,所以先用objdump工具获得反汇编:objdump -d -M intel KCTF.exe > KCTF_objdump.txt,然后对字符串做操作。
(更好的方法应该使用Capstone这样的反汇编引擎,可惜不太熟悉)

代码如下:(与上面的步骤描述有少许不同,但主要思路是一致的)

简单解释一下代码:

其实deobfuscation2之后得到的代码就已经完全没有了混淆,但是注意到里面出现了孤立的VIRTUAL push XXXXXXXX指令,且若干条指令之后一定会在栈平衡的情况下出现一个ret指令。
这种模式其实是函数调用,其中VIRTUAL push XXXXXXXX的常量是压栈的返回地址,即在原始函数中的真实的下一条指令。
deobfuscation2的输出结果是深入调用函数内部后的指令序列;recognize_function函数对这种情况进行了处理,从而恢复出“完整”的原始函数。(缺陷是,由于Block不是真正意义上的基本块,所以原始程序里的条件分支只能看到一条路径,不过问题不大,对另一条路径的起始地址也调用一次该函数即可)

有了解混淆脚本,现在可以分析程序逻辑了

从start函数开始(recognize_function(0x14005FE4C)),找出真正的main函数位于0x140083814
(可以自己写一个小程序再反汇编与之对比)

(在deobfuscation2(0x14005FE4C)的输出中看到调用了很多反调试函数,应该是在main之前的initterm中调用的。从后面的算法看,本题无需动态调试。如果需要调试,只要程序启动后再附加调试器即可)

main函数很长,截取若干个片段如下:(recognize_function的输出)

片段1

可以看出,真正的输入长度为84,下一阶段的检查逻辑在0x1400356b1

片段2

合法的输入字符有42种:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%=

片段3

输入的2个字符被转换为1个字符,转换方式是先转为[0,41]的数字(对应前面的合法字符列表的索引),然后第一个数字*42再加第二个数字

片段4

把输入的84个字符转换为42个整数,要求严格单调递增

片段5

前面得到的42个整数,分别除以42,取整作为横坐标,取余作为纵坐标,要求横纵坐标分别都没有重复(从这里看出,输入的84个字符其实是42个坐标,横纵交替)

片段6

最复杂的检查,二重循环遍历点对,计算纵坐标之差和横坐标之差(如果纵坐标之差为负则两个值都取反),然后计算后者*42+前者,要求这个值不重复(实际上是要求,不存在位置相对值一样的点对)

片段7

最后一处检查,限定了输入的前28个字符(其实依次是42*42棋盘的前14行的点的坐标,每行一个)

检查逻辑有点像N皇后,只不过斜线规则改成了更复杂的点对相对位置检查

求解:回溯法爆破(参考了网上的一段代码),修改了验证规则

算法性能不高,cpython跑不出来,换用pypy3跑了17分钟才出答案

最终答案:

02152S3X4Z5Q6C7T819/ADB%C*DLEIFUG3HRIHJ6K7L0MBNKOJPPQ=RNS+TEUOVWWGXYYMZ9+4-8*F/-%V=A

 
push   rax
push   rax
pushf
call $+5
pop    rax
xor    rax,XXXXXXXX
mov    QWORD PTR [rsp+0x10],rax
popf
pop    rax
push   rax
push   rax
pushf
call $+5
pop    rax
xor    rax,XXXXXXXX
mov    QWORD PTR [rsp+0x10],rax
popf
pop    rax
VIRTUAL push XXXXYYYY
ret
VIRTUAL push XXXXYYYY
ret
push AAA
pop AAA
push AAA
pop AAA
push AAA
push BBB
pop BBB
pop AAA
push AAA
push BBB
pop BBB
pop AAA
push   rax
push   rax
pushf
VIRTUAL push XXXXXXXX
pop    rax
add    rax,YYYYYYYY
mov    QWORD PTR [rsp+0x10],rax
popf
pop    rax
push   rax
push   rax
pushf
VIRTUAL push XXXXXXXX
pop    rax
add    rax,YYYYYYYY
mov    QWORD PTR [rsp+0x10],rax
popf
pop    rax
 
class Instruction:
    __slots__ = ["va", "s"]
    def __init__(self, va, s):
        self.va = va
        self.s = s
    def __str__(self):
        return hex(self.va)+"\t"+self.s
 
class Block:
    __slots__ = ["startva", "jmpva", "insts"]
    def __init__(self):
        self.startva = None
        self.jmpva = None
        self.insts = []
    def __str__(self):
        r = ""
        r += f"; {hex(self.startva)}, {hex(self.jmpva) if self.jmpva else None}:\n"
        for inst in self.insts:
            r += str(inst)+"\n"
        return r
 
    def simplify1(self):
        i = 0
        while (i < len(self.insts)):
            tmp = self.insts[i].s
            i += 1
            if tmp.split()[0] == "push" and i < len(self.insts):
                tmp2 = self.insts[i].s
                i += 1
                if tmp2.split()[0] == "pop" and tmp2.split()[1] == tmp.split()[1]:
                    "push xxx ; pop xxx"
                    i -= 2
                    if self.startva == 0x14007def2:
                        print("xxx", self.insts[i])
                    self.insts.pop(i)
                    self.insts.pop(i)
                else:
                    i -= 1
 
    def simplify2(self):
        i = 0
        while i+8 < len(self.insts):
            if self.insts[i].s.startswith("push   rax") \
               and self.insts[i+1].s.startswith("push   rax") \
               and self.insts[i+2].s.startswith("pushf") \
               and self.insts[i+3].s.startswith("call") \
               and self.insts[i+4].s.startswith("pop    rax") \
               and self.insts[i+5].s.startswith("xor    rax,") \
               and self.insts[i+6].s.startswith("mov    QWORD PTR [rsp+0x10],rax") \
               and self.insts[i+7].s.startswith("popf") \
               and self.insts[i+8].s.startswith("pop    rax"):
                const1 = self.insts[i+4].va
                tmp1 = self.insts[i+3].s
                assert(int(tmp1.split()[1],16) == const1)
                tmp2 = self.insts[i+5].s
                const2 = int(tmp2[tmp2.index(",")+1:], 16)
                newinst = Instruction(self.insts[i].va, f"VIRTUAL push {hex(const1^const2)}")
                for _ in range(9):
                    self.insts.pop(i)
                self.insts.insert(i, newinst)
            i += 1
 
    def simplify3(self):
        i = 0
        while i+8 < len(self.insts):
            if self.insts[i].s.startswith("push   rax") \
               and self.insts[i+1].s.startswith("push   rax") \
               and self.insts[i+2].s.startswith("pushf") \
               and self.insts[i+3].s.startswith("VIRTUAL push") \
               and self.insts[i+4].s.startswith("pop    rax") \
               and self.insts[i+5].s.startswith("add    rax,") \
               and self.insts[i+6].s.startswith("mov    QWORD PTR [rsp+0x10],rax") \
               and self.insts[i+7].s.startswith("popf") \
               and self.insts[i+8].s.startswith("pop    rax"):
                tmp1 = self.insts[i+3].s
                const1 = int(tmp1.split()[2],16)
                tmp2 = self.insts[i+5].s
                const2 = int(tmp2[tmp2.index(",")+1:], 16)
                newinst = Instruction(self.insts[i].va, f"VIRTUAL push {hex((const1+const2) & 0xffffffffffffffff)}")
                for _ in range(9):
                    self.insts.pop(i)
                self.insts.insert(i, newinst)
            i += 1
 
    def simplify4(self):
        if len(self.insts) >= 2:
            if self.insts[-2].s.startswith("VIRTUAL push") \
               and self.insts[-1].s.startswith("ret"):
                tmp1 = self.insts[-2].s
                self.jmpva = int(tmp1.split()[2], 16)
                self.insts.pop(-1)
                self.insts.pop(-1)
 
    def simplify(self):
        lastlen = 0x7fffffff
        while len(self.insts) < lastlen:
            #print("aa", len(self.insts), lastlen)
            lastlen = len(self.insts)
            self.simplify1()
            self.simplify1()
            self.simplify2()
            self.simplify3()
            self.simplify4()
 
with open("KCTF_objdump.txt", "r") as f:
    lines = f.readlines()
 
allinsts = []
instaddr2index = {}
 
def initialize():
    global allinsts
    global instaddr2index
    for line in lines:
        tokens = line.split("\t")
        if len(tokens) == 3:
            va = int(tokens[0].rstrip(":"), 16)
            s = tokens[2].strip()
            if s != "int3":
                #print(hex(addr), s)
                inst = Instruction(va, s)
                allinsts.append(inst)
                instaddr2index[va] = len(allinsts)-1
 
def searchblock(va):
    global allinsts
    global instaddr2index
    bb = Block()
    bb.startva = va
    i = instaddr2index[va]
    while True:
        inst = allinsts[i]
        tokens = inst.s.split()
        bb.insts.append(inst)
        if (tokens[0] == "ret"):
            break
        i += 1
    return bb
 
def mergeblocklist(blocklist):
    bbb = Block()
    bbb.startva = blocklist[0].startva
    bbb.jmpva = blocklist[-1].jmpva
    bbb.insts = []
    for i in range(len(blocklist)):
        bb = blocklist[i]
        bbb.insts.extend(bb.insts)
    return bbb
 
def deobfuscation1(nextva):
    blocklist = []
    seenva = set()
    while nextva and nextva not in seenva:
        seenva.add(nextva)
        #print(hex(nextva))
        bb = searchblock(nextva)
        bb.simplify()
        #print(bb)
        blocklist.append(bb)
        nextva = bb.jmpva
    bbb = mergeblocklist(blocklist)
#    print(bbb)
    bbb.simplify()
#    print(bbb)
    return bbb    # mostly single instruction
 
def deobfuscation2(nextva):
    blocklist = []
    seenva = set()
    while nextva and nextva not in seenva:
        seenva.add(nextva)
        bbb = deobfuscation1(nextva)
        blocklist.append(bbb)
        nextva = bbb.jmpva
    bbbb = mergeblocklist(blocklist)
#    print(bbbb)
    return bbbb    # mostly deep first block instructions
 
 
def recognize_function(va):    # notice: must do block.simplify4 before do this
    blocklist = []
    seenva = set()
    while va and va not in seenva:
        #print(hex(va))
        seenva.add(va)
        block = deobfuscation2(va)
 
        newblock = Block()
        newblock.startva = block.startva
        newblock.jmpva = block.jmpva
        newblock.insts = []
 
        i = 0
        while i < len(block.insts):
            #print(i)
            inst = block.insts[i]
            if inst.s.startswith("VIRTUAL push"):
                const1 = int(inst.s.split()[2],16)
                newblock.insts.append(Instruction(inst.va,f"VIRTUAL call {hex(block.insts[i+1].va)}"))
                newblock.jmpva = const1
                break
            else:
                newblock.insts.append(inst)
            i += 1
        #print("newblock:", newblock)
        blocklist.append(newblock)
        va = newblock.jmpva
 
    bbbbb = mergeblocklist(blocklist)
    print(bbbbb)
    return bbbbb
 
 
initialize()
 
#deobfuscation2(0x14005FE4C)    # start
 
#recognize_function(0x14005FE4C)    # start:part1
#recognize_function(0x1400bf93f)    # start:part2
 
#recognize_function(0x140083814)    # main
class Instruction:
    __slots__ = ["va", "s"]
    def __init__(self, va, s):
        self.va = va
        self.s = s
    def __str__(self):
        return hex(self.va)+"\t"+self.s
 
class Block:
    __slots__ = ["startva", "jmpva", "insts"]
    def __init__(self):
        self.startva = None
        self.jmpva = None
        self.insts = []
    def __str__(self):
        r = ""
        r += f"; {hex(self.startva)}, {hex(self.jmpva) if self.jmpva else None}:\n"
        for inst in self.insts:
            r += str(inst)+"\n"
        return r
 
    def simplify1(self):
        i = 0
        while (i < len(self.insts)):
            tmp = self.insts[i].s
            i += 1
            if tmp.split()[0] == "push" and i < len(self.insts):
                tmp2 = self.insts[i].s
                i += 1
                if tmp2.split()[0] == "pop" and tmp2.split()[1] == tmp.split()[1]:
                    "push xxx ; pop xxx"
                    i -= 2
                    if self.startva == 0x14007def2:
                        print("xxx", self.insts[i])
                    self.insts.pop(i)
                    self.insts.pop(i)
                else:
                    i -= 1
 
    def simplify2(self):
        i = 0
        while i+8 < len(self.insts):
            if self.insts[i].s.startswith("push   rax") \
               and self.insts[i+1].s.startswith("push   rax") \
               and self.insts[i+2].s.startswith("pushf") \
               and self.insts[i+3].s.startswith("call") \
               and self.insts[i+4].s.startswith("pop    rax") \
               and self.insts[i+5].s.startswith("xor    rax,") \
               and self.insts[i+6].s.startswith("mov    QWORD PTR [rsp+0x10],rax") \
               and self.insts[i+7].s.startswith("popf") \
               and self.insts[i+8].s.startswith("pop    rax"):
                const1 = self.insts[i+4].va
                tmp1 = self.insts[i+3].s
                assert(int(tmp1.split()[1],16) == const1)
                tmp2 = self.insts[i+5].s
                const2 = int(tmp2[tmp2.index(",")+1:], 16)
                newinst = Instruction(self.insts[i].va, f"VIRTUAL push {hex(const1^const2)}")
                for _ in range(9):
                    self.insts.pop(i)
                self.insts.insert(i, newinst)
            i += 1
 
    def simplify3(self):
        i = 0
        while i+8 < len(self.insts):
            if self.insts[i].s.startswith("push   rax") \
               and self.insts[i+1].s.startswith("push   rax") \
               and self.insts[i+2].s.startswith("pushf") \
               and self.insts[i+3].s.startswith("VIRTUAL push") \
               and self.insts[i+4].s.startswith("pop    rax") \
               and self.insts[i+5].s.startswith("add    rax,") \
               and self.insts[i+6].s.startswith("mov    QWORD PTR [rsp+0x10],rax") \
               and self.insts[i+7].s.startswith("popf") \
               and self.insts[i+8].s.startswith("pop    rax"):
                tmp1 = self.insts[i+3].s
                const1 = int(tmp1.split()[2],16)
                tmp2 = self.insts[i+5].s
                const2 = int(tmp2[tmp2.index(",")+1:], 16)
                newinst = Instruction(self.insts[i].va, f"VIRTUAL push {hex((const1+const2) & 0xffffffffffffffff)}")
                for _ in range(9):
                    self.insts.pop(i)
                self.insts.insert(i, newinst)
            i += 1
 
    def simplify4(self):
        if len(self.insts) >= 2:
            if self.insts[-2].s.startswith("VIRTUAL push") \
               and self.insts[-1].s.startswith("ret"):
                tmp1 = self.insts[-2].s
                self.jmpva = int(tmp1.split()[2], 16)
                self.insts.pop(-1)
                self.insts.pop(-1)
 
    def simplify(self):
        lastlen = 0x7fffffff
        while len(self.insts) < lastlen:
            #print("aa", len(self.insts), lastlen)
            lastlen = len(self.insts)
            self.simplify1()
            self.simplify1()
            self.simplify2()
            self.simplify3()
            self.simplify4()
 
with open("KCTF_objdump.txt", "r") as f:
    lines = f.readlines()
 
allinsts = []
instaddr2index = {}
 
def initialize():
    global allinsts
    global instaddr2index
    for line in lines:
        tokens = line.split("\t")
        if len(tokens) == 3:
            va = int(tokens[0].rstrip(":"), 16)
            s = tokens[2].strip()
            if s != "int3":
                #print(hex(addr), s)
                inst = Instruction(va, s)
                allinsts.append(inst)
                instaddr2index[va] = len(allinsts)-1
 
def searchblock(va):
    global allinsts
    global instaddr2index
    bb = Block()
    bb.startva = va
    i = instaddr2index[va]
    while True:
        inst = allinsts[i]
        tokens = inst.s.split()
        bb.insts.append(inst)
        if (tokens[0] == "ret"):
            break
        i += 1
    return bb
 
def mergeblocklist(blocklist):
    bbb = Block()
    bbb.startva = blocklist[0].startva
    bbb.jmpva = blocklist[-1].jmpva
    bbb.insts = []
    for i in range(len(blocklist)):
        bb = blocklist[i]
        bbb.insts.extend(bb.insts)
    return bbb
 
def deobfuscation1(nextva):
    blocklist = []
    seenva = set()
    while nextva and nextva not in seenva:
        seenva.add(nextva)
        #print(hex(nextva))
        bb = searchblock(nextva)
        bb.simplify()
        #print(bb)
        blocklist.append(bb)
        nextva = bb.jmpva
    bbb = mergeblocklist(blocklist)
#    print(bbb)
    bbb.simplify()
#    print(bbb)
    return bbb    # mostly single instruction
 
def deobfuscation2(nextva):
    blocklist = []
    seenva = set()
    while nextva and nextva not in seenva:
        seenva.add(nextva)
        bbb = deobfuscation1(nextva)
        blocklist.append(bbb)
        nextva = bbb.jmpva
    bbbb = mergeblocklist(blocklist)
#    print(bbbb)
    return bbbb    # mostly deep first block instructions
 
 
def recognize_function(va):    # notice: must do block.simplify4 before do this
    blocklist = []
    seenva = set()
    while va and va not in seenva:
        #print(hex(va))
        seenva.add(va)
        block = deobfuscation2(va)
 
        newblock = Block()
        newblock.startva = block.startva
        newblock.jmpva = block.jmpva
        newblock.insts = []
 
        i = 0
        while i < len(block.insts):
            #print(i)
            inst = block.insts[i]
            if inst.s.startswith("VIRTUAL push"):
                const1 = int(inst.s.split()[2],16)
                newblock.insts.append(Instruction(inst.va,f"VIRTUAL call {hex(block.insts[i+1].va)}"))
                newblock.jmpva = const1
                break
            else:
                newblock.insts.append(inst)
            i += 1
        #print("newblock:", newblock)
        blocklist.append(newblock)
        va = newblock.jmpva
 
    bbbbb = mergeblocklist(blocklist)
    print(bbbbb)
    return bbbbb
 
 
initialize()
 
#deobfuscation2(0x14005FE4C)    # start
 
#recognize_function(0x14005FE4C)    # start:part1
#recognize_function(0x1400bf93f)    # start:part2
 
#recognize_function(0x140083814)    # main
 
 
 
 
0x14000f17c    VIRTUAL call 0x140026de8    # call std::cin
0x14001eb47    lea    rcx,[rsp+0x1010]
0x14003a798    lea    rdx,[rip+0xfffffffffffc9ddf]        # *** 0x14000457e, char[] "1743"
0x1400beaab    mov    QWORD PTR [rsp+0x50],rax
0x140002c25    VIRTUAL call 0x1400d4a33    # *** 140004C88, strcmp with "1743"  # 0x1400d4a33
0x1400f1dda    movsxd rcx,eax
0x14009f9b9    cmp    rcx,0x0
0x1400a988a    jne    0x1400a98a3    # 0x1400dab0e
0x14009954a    lea    rcx,[rip+0xfffffffffff6af6d]        # 0x1400044be    # " >>> 阁下的数学功底十分扎实,只可惜与在下的绝世武学无缘,请回吧。"
0x14002587c    VIRTUAL call 0x1400cd482
0x1400dab0e    lea    rcx,[rsp+0x1010]
0x14008475a    VIRTUAL call 0x140050476    # get input string length
0x140083333    cmp    rax,0x54    # 84
0x140035698    je     0x1400356b1
0x140048e00    lea    rcx,[rip+0xfffffffffffbb695]        # 0x14000449c    # " >>> 阁下的数学成绩堪忧,请回吧。"
0x14000f17c    VIRTUAL call 0x140026de8    # call std::cin
0x14001eb47    lea    rcx,[rsp+0x1010]
0x14003a798    lea    rdx,[rip+0xfffffffffffc9ddf]        # *** 0x14000457e, char[] "1743"
0x1400beaab    mov    QWORD PTR [rsp+0x50],rax
0x140002c25    VIRTUAL call 0x1400d4a33    # *** 140004C88, strcmp with "1743"  # 0x1400d4a33
0x1400f1dda    movsxd rcx,eax
0x14009f9b9    cmp    rcx,0x0
0x1400a988a    jne    0x1400a98a3    # 0x1400dab0e
0x14009954a    lea    rcx,[rip+0xfffffffffff6af6d]        # 0x1400044be    # " >>> 阁下的数学功底十分扎实,只可惜与在下的绝世武学无缘,请回吧。"
0x14002587c    VIRTUAL call 0x1400cd482
0x1400dab0e    lea    rcx,[rsp+0x1010]
0x14008475a    VIRTUAL call 0x140050476    # get input string length
0x140083333    cmp    rax,0x54    # 84
0x140035698    je     0x1400356b1
0x140048e00    lea    rcx,[rip+0xfffffffffffbb695]        # 0x14000449c    # " >>> 阁下的数学成绩堪忧,请回吧。"
; 0x1400877ad, None:
0x1400877ad    push   rax
0x1400da463    mov    BYTE PTR [rsp+0x7],cl
0x1400254a5    movsx  eax,BYTE PTR [rsp+0x7]
0x140027b39    cmp    eax,0x30
0x140087ceb    jl     0x140087d04    # 0x140045036
0x1400d1b0f    movsx  eax,BYTE PTR [rsp+0x7]
0x1400cbfad    cmp    eax,0x39
0x140032877    mov    cl,0x1
0x14004cbd4    mov    BYTE PTR [rsp+0x6],cl
0x14005134f    jle    0x140051368
0x140045036    movsx  eax,BYTE PTR [rsp+0x7]
0x1400a27a9    cmp    eax,0x41
0x1400db7db    jl     0x1400db7f4
0x1400dabed    movsx  eax,BYTE PTR [rsp+0x7]
0x1400a07d9    cmp    eax,0x5a
0x1400ed537    mov    cl,0x1
0x140025ead    mov    BYTE PTR [rsp+0x6],cl
0x140032ada    jle    0x140032af3    # 0x14005e3af
0x1400388fa    movsx  eax,BYTE PTR [rsp+0x7]
0x140045713    cmp    eax,0x2b
0x1400779b8    mov    cl,0x1
0x1400ca53a    mov    BYTE PTR [rsp+0x6],cl
0x1400bdc5a    je     0x1400bdc73    # 0x14005e3af
0x1400b40d3    movsx  eax,BYTE PTR [rsp+0x7]
0x140071b51    cmp    eax,0x2d
0x140031fa6    mov    cl,0x1
0x1400a85c9    mov    BYTE PTR [rsp+0x6],cl
0x140021689    je     0x1400216a2
0x140059269    movsx  eax,BYTE PTR [rsp+0x7]
0x1400f5da9    cmp    eax,0x2a
0x140067a65    mov    cl,0x1
0x1400477a2    mov    BYTE PTR [rsp+0x6],cl
0x14005d81b    je     0x14005d834
0x140082dcc    movsx  eax,BYTE PTR [rsp+0x7]
0x140014c52    cmp    eax,0x2f
0x1400afc6d    mov    cl,0x1
0x14006091f    mov    BYTE PTR [rsp+0x6],cl
0x1400020ec    je     0x140002105
0x1400dde99    movsx  eax,BYTE PTR [rsp+0x7]
0x140081c7a    cmp    eax,0x25
0x1400f43b2    mov    cl,0x1
0x1400200b9    mov    BYTE PTR [rsp+0x6],cl
0x1400819ac    je     0x1400819c5
0x140085a98    movsx  eax,BYTE PTR [rsp+0x7]
0x140003a93    cmp    eax,0x3d
0x1400f9bac    sete   cl
0x140080797    mov    BYTE PTR [rsp+0x6],cl
0x14005e3af    mov    al,BYTE PTR [rsp+0x6]
0x14006e388    and    al,0x1
0x1400bd7f2    movzx  eax,al
0x1400d73bf    pop    rcx
0x140095d39    ret
; 0x1400877ad, None:
0x1400877ad    push   rax
0x1400da463    mov    BYTE PTR [rsp+0x7],cl
0x1400254a5    movsx  eax,BYTE PTR [rsp+0x7]
0x140027b39    cmp    eax,0x30
0x140087ceb    jl     0x140087d04    # 0x140045036
0x1400d1b0f    movsx  eax,BYTE PTR [rsp+0x7]
0x1400cbfad    cmp    eax,0x39
0x140032877    mov    cl,0x1
0x14004cbd4    mov    BYTE PTR [rsp+0x6],cl
0x14005134f    jle    0x140051368
0x140045036    movsx  eax,BYTE PTR [rsp+0x7]
0x1400a27a9    cmp    eax,0x41
0x1400db7db    jl     0x1400db7f4
0x1400dabed    movsx  eax,BYTE PTR [rsp+0x7]
0x1400a07d9    cmp    eax,0x5a
0x1400ed537    mov    cl,0x1
0x140025ead    mov    BYTE PTR [rsp+0x6],cl
0x140032ada    jle    0x140032af3    # 0x14005e3af
0x1400388fa    movsx  eax,BYTE PTR [rsp+0x7]
0x140045713    cmp    eax,0x2b
0x1400779b8    mov    cl,0x1
0x1400ca53a    mov    BYTE PTR [rsp+0x6],cl
0x1400bdc5a    je     0x1400bdc73    # 0x14005e3af
0x1400b40d3    movsx  eax,BYTE PTR [rsp+0x7]
0x140071b51    cmp    eax,0x2d
0x140031fa6    mov    cl,0x1
0x1400a85c9    mov    BYTE PTR [rsp+0x6],cl
0x140021689    je     0x1400216a2
0x140059269    movsx  eax,BYTE PTR [rsp+0x7]
0x1400f5da9    cmp    eax,0x2a
0x140067a65    mov    cl,0x1
0x1400477a2    mov    BYTE PTR [rsp+0x6],cl
0x14005d81b    je     0x14005d834
0x140082dcc    movsx  eax,BYTE PTR [rsp+0x7]
0x140014c52    cmp    eax,0x2f
0x1400afc6d    mov    cl,0x1
0x14006091f    mov    BYTE PTR [rsp+0x6],cl
0x1400020ec    je     0x140002105
0x1400dde99    movsx  eax,BYTE PTR [rsp+0x7]
0x140081c7a    cmp    eax,0x25
0x1400f43b2    mov    cl,0x1
0x1400200b9    mov    BYTE PTR [rsp+0x6],cl
0x1400819ac    je     0x1400819c5
0x140085a98    movsx  eax,BYTE PTR [rsp+0x7]
0x140003a93    cmp    eax,0x3d
0x1400f9bac    sete   cl
0x140080797    mov    BYTE PTR [rsp+0x6],cl
0x14005e3af    mov    al,BYTE PTR [rsp+0x6]

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-5-19 00:30 被mb_mgodlfyn编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//