L3HCTF 2021 Reverse 两道题解 (IDAAAAAA double-joy)

这波reverse全军覆没了属于是,最后1/7。。然后队友依然打到了rank3 orz orz

自己全场只看了两个题,最后0输出,麻了。

IDAAAAAA

这题tmd是个misc题吧

tag: 细节+脑洞

错误的分析方法:dump出来elf然后gdb调试

只给了idb,没有elf,直接打开发现是一个将输入解析为按照+号和-号分隔开的三个数字,比如输入-123+5+6,就会得到-123,5,6三个数字。然后这三个数字直接静态看的话必须满足5个约束条件:

image.png

但是直接在2^32的域上求解这5个方程是求不出解的,然后大家就都懵逼了,甚至开始尝试从中选三个出来解。但是这样即使把所有的情况都解出来也是错误的

正确的分析方法:看给的idb

这个idb其实一打开可以发现有一个断点,我当时脑子里大概有一秒钟疑惑了下为啥有个断点,然后就没管他。。然后就错过了

后面我直接用IDA连gdbserver调试的时候,会发现每次执行完scanf都会直接运行结束,当时以为是IDA抽风了。。没想到是故意的,但凡多想一下这个flag也到手了

然后进入正题,这个断点右键编辑,会发现里面的condition是有idapython脚本的(脚本很长,打开这个断点的时候IDA会卡一会儿):

image.png

撸出来之后:

global jIS40A
jIS40A = [...] # 一个长度1000的list,每个item是一堆bytes
N4QKUt = 0
EpUdLx = 4728923
idaapi.add_bpt(EpUdLx)
uwGgnM = idaapi.bpt_t()
idaapi.get_bpt(EpUdLx, uwGgnM)
uwGgnM.elang = "Python"
uwGgnM.condition = "N4QKUt = {}\n".format(N4QKUt) + 'VLzxDy = idaapi.get_byte(5127584 + N4QKUt)\nVLzxDy -= ord(\'a\')\nif VLzxDy == 0:\n    bYsMTa = 287\n    LjzrdT = b\'lqAT7pNI3BX\'\nelif VLzxDy == 1:\n    bYsMTa = 96\n    LjzrdT = b\'z3Uhis74aPq\'\nelif VLzxDy == 2:\n    bYsMTa = 8\n    LjzrdT = b\'9tjseMGBHR5\'\nelif VLzxDy == 3:\n    bYsMTa = 777\n    LjzrdT = b\'FhnvgMQjexH\'\nelif VLzxDy == 4:\n    bYsMTa = 496\n    LjzrdT = b\'SKnZ51f9WsE\'\nelif VLzxDy == 5:\n    bYsMTa = 822\n    LjzrdT = b\'gDJy104BSHW\'\nelif VLzxDy == 6:\n    bYsMTa = 914\n    LjzrdT = b\'PbRV4rSM7fd\'\nelif VLzxDy == 7:\n    bYsMTa = 550\n    LjzrdT = b\'WHPnoMTsbx3\'\nelif VLzxDy == 8:\n    bYsMTa = 273\n    LjzrdT = b\'mLx5hvlqufG\'\nelif VLzxDy == 9:\n    bYsMTa = 259\n    LjzrdT = b\'QvKgNmUFTnW\'\nelif VLzxDy == 10:\n    bYsMTa = 334\n    LjzrdT = b\'TCrHaitRfY1\'\nelif VLzxDy == 11:\n    bYsMTa = 966\n    LjzrdT = b\'m26IAvjq1zC\'\nelif VLzxDy == 12:\n    bYsMTa = 331\n    LjzrdT = b\'dQb2ufTZwLX\'\nelif VLzxDy == 13:\n    bYsMTa = 680\n    LjzrdT = b\'Y6Sr7znOeHL\'\nelif VLzxDy == 14:\n    bYsMTa = 374\n    LjzrdT = b\'hLFj1wl5A0U\'\nelif VLzxDy == 15:\n    bYsMTa = 717\n    LjzrdT = b\'H6W03R7TLFe\'\nelif VLzxDy == 16:\n    bYsMTa = 965\n    LjzrdT = b\'fphoJwDKsTv\'\nelif VLzxDy == 17:\n    bYsMTa = 952\n    LjzrdT = b\'CMF1Vk7NH4O\'\nelif VLzxDy == 18:\n    bYsMTa = 222\n    LjzrdT = b\'43PSbAlgLqj\'\nelse:\n    bYsMTa = -1\nif bYsMTa < 0:\n    cpu.rsp -= 8\n    cpu.rdi = 4927649\n    cpu.rax = 0\n    idaapi.patch_qword(cpu.rsp, 4202616)\n    idaapi.del_bpt(cpu.rip)\n    cpu.rip = 4263680\nelse:\n    zaqhdD = 0x486195\n    bYsMTa = jIS40A[bYsMTa]\n\n    idaapi.patch_bytes(5117568, bYsMTa)\n    idaapi.patch_bytes(5117488, LjzrdT)\n\n    cpu.rsp -= 8\n    idaapi.patch_qword(cpu.rsp, zaqhdD)\n    cpu.rdi = 5117568\n    cpu.rsi = len(bYsMTa)\n    cpu.rdx = 5117488\n    cpu.rcx = 11\n    cpu.r8 = 5117568\n    cpu.rax = 5117568\n\n    idaapi.add_bpt(zaqhdD)\n    jQfwUA = idaapi.bpt_t()\n    idaapi.get_bpt(zaqhdD, jQfwUA)\n    jQfwUA.elang = "Python"\n    jQfwUA.condition = "N4QKUt = {}\\nSdjOr3 = {}\\n".format(N4QKUt, len(bYsMTa)) + \'bYsMTa = idaapi.get_bytes(cpu.rax, SdjOr3).decode()\\nzaqhdD = 4767838\\nidaapi.add_bpt(zaqhdD)\\njQfwUA = idaapi.bpt_t()\\nidaapi.get_bpt(zaqhdD, jQfwUA)\\njQfwUA.elang = "Python"\\njQfwUA.condition = "N4QKUt = {}\\\\n".format(N4QKUt+1) + bYsMTa\\nidaapi.del_bpt(zaqhdD)\\nidaapi.add_bpt(jQfwUA)\\nidaapi.del_bpt(cpu.rip)\\ncpu.rsp -= 8\\nidaapi.patch_qword(cpu.rsp, zaqhdD)\\ncpu.rip = 4447160\\n\'\n    idaapi.del_bpt(zaqhdD)\n    idaapi.add_bpt(jQfwUA)\n    idaapi.del_bpt(cpu.rip)\n    cpu.rip = 4201909\n'
idaapi.del_bpt(EpUdLx)
idaapi.add_bpt(uwGgnM)
cpu.rsp -= 8
idaapi.patch_qword(cpu.rsp, EpUdLx)
cpu.rip = 4202096

不难发现是在这个脚本里面设置了新的断点,而且在新的断点里面加入了新的condition脚本,然后移动eip到一个能执行到断点的位置,我们condition里面的字节解析出来是:

N4QKUt = 0
VLzxDy = idaapi.get_byte(0x4e3da0 + N4QKUt) # user input
VLzxDy -= ord('a')
if VLzxDy == 0:
    bYsMTa = 287
    LjzrdT = b'lqAT7pNI3BX'
elif VLzxDy == 1:
    bYsMTa = 96
    LjzrdT = b'z3Uhis74aPq'
elif VLzxDy == 2:
    bYsMTa = 8
    LjzrdT = b'9tjseMGBHR5'
elif VLzxDy == 3:
    bYsMTa = 777
    LjzrdT = b'FhnvgMQjexH'
elif VLzxDy == 4:
    bYsMTa = 496
    LjzrdT = b'SKnZ51f9WsE'
elif VLzxDy == 5:
    bYsMTa = 822
    LjzrdT = b'gDJy104BSHW'
elif VLzxDy == 6:
    bYsMTa = 914
    LjzrdT = b'PbRV4rSM7fd'
elif VLzxDy == 7:
    bYsMTa = 550
    LjzrdT = b'WHPnoMTsbx3'
elif VLzxDy == 8:
    bYsMTa = 273
    LjzrdT = b'mLx5hvlqufG'
elif VLzxDy == 9:
    bYsMTa = 259
    LjzrdT = b'QvKgNmUFTnW'
elif VLzxDy == 10:
    bYsMTa = 334
    LjzrdT = b'TCrHaitRfY1'
elif VLzxDy == 11:
    bYsMTa = 966
    LjzrdT = b'm26IAvjq1zC'
elif VLzxDy == 12:
    bYsMTa = 331
    LjzrdT = b'dQb2ufTZwLX'
elif VLzxDy == 13:
    bYsMTa = 680
    LjzrdT = b'Y6Sr7znOeHL'
elif VLzxDy == 14:
    bYsMTa = 374
    LjzrdT = b'hLFj1wl5A0U'
elif VLzxDy == 15:
    bYsMTa = 717
    LjzrdT = b'H6W03R7TLFe'
elif VLzxDy == 16:
    bYsMTa = 965
    LjzrdT = b'fphoJwDKsTv'
elif VLzxDy == 17:
    bYsMTa = 952
    LjzrdT = b'CMF1Vk7NH4O'
elif VLzxDy == 18:
    bYsMTa = 222
    LjzrdT = b'43PSbAlgLqj'
else:
    bYsMTa = -1
if bYsMTa < 0:
    cpu.rsp -= 8
    cpu.rdi = 0x4b30a1
    cpu.rax = 0
    idaapi.patch_qword(cpu.rsp, 4202616)
    idaapi.del_bpt(cpu.rip)
    cpu.rip = 0x410f00
else:
    zaqhdD = 0x486195
    bYsMTa = jIS40A[bYsMTa]

    idaapi.patch_bytes(0x4e1680, bYsMTa)
    idaapi.patch_bytes(0x4e1630, LjzrdT)

    cpu.rsp -= 8
    idaapi.patch_qword(cpu.rsp, zaqhdD)
    cpu.rdi = 0x4e1680 #src
    cpu.rsi = len(bYsMTa) #len
    cpu.rdx = 0x4e1630 #key
    cpu.rcx = 11 #key len
    cpu.r8 = 0x4e1680 #dst
    cpu.rax = 0x4e1680

    idaapi.add_bpt(zaqhdD)
    jQfwUA = idaapi.bpt_t()
    idaapi.get_bpt(zaqhdD, jQfwUA)
    jQfwUA.elang = "Python"
    jQfwUA.condition = "N4QKUt = {}\nSdjOr3 = {}\n".format(N4QKUt, len(bYsMTa)) + 'bYsMTa = idaapi.get_bytes(cpu.rax, SdjOr3).decode()\nzaqhdD = 4767838\nidaapi.add_bpt(zaqhdD)\njQfwUA = idaapi.bpt_t()\nidaapi.get_bpt(zaqhdD, jQfwUA)\njQfwUA.elang = "Python"\njQfwUA.condition = "N4QKUt = {}\\n".format(N4QKUt+1) + bYsMTa\nidaapi.del_bpt(zaqhdD)\nidaapi.add_bpt(jQfwUA)\nidaapi.del_bpt(cpu.rip)\ncpu.rsp -= 8\nidaapi.patch_qword(cpu.rsp, zaqhdD)\ncpu.rip = 4447160\n'
    idaapi.del_bpt(zaqhdD)
    idaapi.add_bpt(jQfwUA)
    idaapi.del_bpt(cpu.rip)
    cpu.rip = 0x401db5 # decrypt

可以发现逻辑是根据输入(存储在byte_4E3DA0)的第一个字符减去a的值来选择全局bytes数组jIS40A中的对应项,然后跳转到sub_401DB5继续执行。打开sub_401DB5可以发现是一个XOR解密函数,密钥由rdx指向,长度为11。

image.png

在if else列表里随便选一个,从jIS40A里找到对应的bytes,解密后发现是一个新的相同结构脚本:

image.png

这时候其实逻辑就比较清晰了,jIS40A中的每一项是一个加密后的脚本,每个脚本解密后将根据用户输入的字符跳转到对应的下一个脚本继续执行。结合字符串中的提示flag is L3HCTF{md5($SHORTEST_VALID_INPUT)},我们就可以将每个脚本看作有向图上的一个点,找到最终的终止点,然后跑一遍最短路就完事了。完整的脚本(不包含jIS40A,那玩意太长了 = =):

def decrypt(ct, key):
    res=b''
    for i,b in enumerate(ct):
        res+= (b ^ key[i%11]).to_bytes(1,"little")
    return res

def getNextList(cryptedBytes)-> list:
    pos=cryptedBytes.find(b'ord(\'a\')\n') 
    nextList=[]
    while True:
        edge = { 'id': 0, 'v': 0, 'key': b''}
        pos=cryptedBytes.find(b'==', pos)
        if pos == -1: # last else
            break
        eolpos = cryptedBytes.find(b':\n', pos)
        edge['id'] = eval(cryptedBytes[pos+2:eolpos]) # next id 0,1,2,3..

        pos=cryptedBytes.find(b'=', pos+2)
        eolpos = cryptedBytes.find(b'\n', pos)
        edge['v']= eval(cryptedBytes[pos+1:eolpos]) # next node

        pos=cryptedBytes.find(b'=', pos+1)
        eolpos = cryptedBytes.find(b'\n', pos)
        edge['key']= eval(cryptedBytes[pos+1:eolpos]) # next node

        nextList.append(edge)

    return nextList

rootBytes=b'VLzxDy = idaapi.get_byte(5127584 + N4QKUt)\nVLzxDy -= ord(\'a\')\nif VLzxDy == 0:\n    bYsMTa = 287\n    LjzrdT = b\'lqAT7pNI3BX\'\nelif VLzxDy == 1:\n    bYsMTa = 96\n    LjzrdT = b\'z3Uhis74aPq\'\nelif VLzxDy == 2:\n    bYsMTa = 8\n    LjzrdT = b\'9tjseMGBHR5\'\nelif VLzxDy == 3:\n    bYsMTa = 777\n    LjzrdT = b\'FhnvgMQjexH\'\nelif VLzxDy == 4:\n    bYsMTa = 496\n    LjzrdT = b\'SKnZ51f9WsE\'\nelif VLzxDy == 5:\n    bYsMTa = 822\n    LjzrdT = b\'gDJy104BSHW\'\nelif VLzxDy == 6:\n    bYsMTa = 914\n    LjzrdT = b\'PbRV4rSM7fd\'\nelif VLzxDy == 7:\n    bYsMTa = 550\n    LjzrdT = b\'WHPnoMTsbx3\'\nelif VLzxDy == 8:\n    bYsMTa = 273\n    LjzrdT = b\'mLx5hvlqufG\'\nelif VLzxDy == 9:\n    bYsMTa = 259\n    LjzrdT = b\'QvKgNmUFTnW\'\nelif VLzxDy == 10:\n    bYsMTa = 334\n    LjzrdT = b\'TCrHaitRfY1\'\nelif VLzxDy == 11:\n    bYsMTa = 966\n    LjzrdT = b\'m26IAvjq1zC\'\nelif VLzxDy == 12:\n    bYsMTa = 331\n    LjzrdT = b\'dQb2ufTZwLX\'\nelif VLzxDy == 13:\n    bYsMTa = 680\n    LjzrdT = b\'Y6Sr7znOeHL\'\nelif VLzxDy == 14:\n    bYsMTa = 374\n    LjzrdT = b\'hLFj1wl5A0U\'\nelif VLzxDy == 15:\n    bYsMTa = 717\n    LjzrdT = b\'H6W03R7TLFe\'\nelif VLzxDy == 16:\n    bYsMTa = 965\n    LjzrdT = b\'fphoJwDKsTv\'\nelif VLzxDy == 17:\n    bYsMTa = 952\n    LjzrdT = b\'CMF1Vk7NH4O\'\nelif VLzxDy == 18:\n    bYsMTa = 222\n    LjzrdT = b\'43PSbAlgLqj\'\nelse:\n    bYsMTa = -1\nif bYsMTa < 0:\n    cpu.rsp -= 8\n    cpu.rdi = 4927649\n    cpu.rax = 0\n    idaapi.patch_qword(cpu.rsp, 4202616)\n    idaapi.del_bpt(cpu.rip)\n    cpu.rip = 4263680\nelse:\n    zaqhdD = 0x486195\n    bYsMTa = jIS40A[bYsMTa]\n\n    idaapi.patch_bytes(5117568, bYsMTa)\n    idaapi.patch_bytes(5117488, LjzrdT)\n\n    cpu.rsp -= 8\n    idaapi.patch_qword(cpu.rsp, zaqhdD)\n    cpu.rdi = 5117568\n    cpu.rsi = len(bYsMTa)\n    cpu.rdx = 5117488\n    cpu.rcx = 11\n    cpu.r8 = 5117568\n    cpu.rax = 5117568\n\n    idaapi.add_bpt(zaqhdD)\n    jQfwUA = idaapi.bpt_t()\n    idaapi.get_bpt(zaqhdD, jQfwUA)\n    jQfwUA.elang = "Python"\n    jQfwUA.condition = "N4QKUt = {}\\nSdjOr3 = {}\\n".format(N4QKUt, len(bYsMTa)) + \'bYsMTa = idaapi.get_bytes(cpu.rax, SdjOr3).decode()\\nzaqhdD = 4767838\\nidaapi.add_bpt(zaqhdD)\\njQfwUA = idaapi.bpt_t()\\nidaapi.get_bpt(zaqhdD, jQfwUA)\\njQfwUA.elang = "Python"\\njQfwUA.condition = "N4QKUt = {}\\\\n".format(N4QKUt+1) + bYsMTa\\nidaapi.del_bpt(zaqhdD)\\nidaapi.add_bpt(jQfwUA)\\nidaapi.del_bpt(cpu.rip)\\ncpu.rsp -= 8\\nidaapi.patch_qword(cpu.rsp, zaqhdD)\\ncpu.rip = 4447160\\n\'\n    idaapi.del_bpt(zaqhdD)\n    idaapi.add_bpt(jQfwUA)\n    idaapi.del_bpt(cpu.rip)\n    cpu.rip = 4201909\n'

G={}
root=0
vis=[0 for i in range(1000)]
# G[root]=getNextList(rootBytes)
# print(G[root])

def buildG(cur: int, curBytes):
    if vis[cur] != 0:
        return
    vis[cur]=1
    curStruct = {}
    curStruct['plaintext'] = curBytes
    curStruct['nextList'] = getNextList(curBytes)
    G[cur]=curStruct
    for e in curStruct['nextList']:
        nextBytes = jIS40A[e['v']]
        nextBytes = decrypt(nextBytes, e['key'])
        buildG(e['v'], nextBytes)

buildG(root, rootBytes)

for n, s in G.items():
    if len(s['nextList']) == 0:
        print(n)
        print(s['plaintext'].decode())
        print("len is %d"%len(s['plaintext']))

import queue

def dij(s:int, t:int)->(int, list):
    dis=[0x3f3f3f3f for i in range(1000)]
    done=[0 for i in range(1000)]
    path=[-1 for i in range(1000)]
    pathId=[-1 for i in range(1000)]
    dis[s]=0
    que = queue.PriorityQueue()
    que.put([0, s])
    while not que.empty() :
        [cdis, cur] = que.get()
        if done[cur] != 0 :
            continue
        done[cur]=1
        if cur == t:
            break
        for e in G[cur]['nextList']:
            if dis[e['v']] > cdis + 1:
                dis[e['v']] = cdis + 1
                path[e['v']] = cur
                pathId[e['v']] = e['id']
                que.put([dis[e['v']], e['v']])
    validInput = []
    cur = t
    while cur != s:
        c = pathId[cur]
        validInput.append(chr(ord('a')+c))
        cur = path[cur]
    validInput.reverse()
    return validInput

result= dij(0,426)
print(''.join(dij(0,426)))

double-joy

tag: C++ STL deque + 虚拟机

VM的opcode:

// 传进来的参数结构体存储了一个虚拟机的状态
struct astruct {
    _BYTE * field_0x0;// 指向opcode,相当于代码段
    _BYTE * buf;//前一段包含了main里输入的input,后面作为虚拟机的伪堆栈(不过感觉所有的操作都只用了不超过2个栈上的元素?)后续伪堆栈上的操作都是4字节对齐的
    _DWORD n1;// 虚拟机的pc指针相对于field_0x0的偏移
    _DWORD n2;// 虚拟机的sp指针相对于buf的偏移
};

undefined4 FUN_00101d90(astruct *param_1)

{
    uint *puVar1;
    unsigned char bVar2;
    uint uVar3;
    uint uVar4;
    undefined4 uVar5;
    char *pcVar6;
    int iVar7;
    int *piVar8;
    long lVar9;
    int iVar10;
    int iVar11;
    long lVar12;
    uint *puVar13;

    lVar9 = param_1->field_0x0;
    puVar13 = &switchD_00101dc4::switchdataD_00103004;
    iVar10 = param_1->n1;
LAB_00101da8:
    lVar12 = (long)iVar10;
    while (true)
    {                                               
        bVar2 = *(unsigned char *)(lVar9 + lVar12); 
        iVar11 = (int)lVar12;
        iVar10 = iVar11 + 1;
        param_1->n1 = iVar10;
        if (bVar2 < 0x13)
            break;
        lVar12 = lVar12 + 1;
    }
    switch ((long)(int)puVar13[bVar2] + (long)puVar13)
    {
    case 0x101dd0://0x11 
        goto switchD_00101dc4_caseD_101dd0;
    case 0x101de8://0x10 如果栈顶元素为0,则PC+5,否则PC+0x10后面跟的立即数,某种条件跳转
        iVar11 = iVar11 + 5;//v11+=5
        iVar7 = param_1->n2 + -1; // n2-=1
        param_1->n2 = iVar7;
        if (*(int *)(param_1->buf + (long)iVar7 * 4) == 0)//buf[n2] as int == 0
        {
            param_1->n1 = iVar11;//n1=v11
            iVar10 = iVar11;//v10=v11
        }
        else
        {
            iVar10 = iVar11 + *(int *)(lVar9 + iVar10);//v10=v11+field_0x0[iVar10]
            param_1->n1 = iVar10;
        }
        goto LAB_00101da8;
    case 0x101e18://0x0F 类似JMP,PC=PC+后面的跟的立即数+4
        iVar10 = *(int *)(lVar9 + iVar10) + 5 + iVar11;// n1 = v10 = filed[v10]+5+v11
        param_1->n1 = iVar10;
        goto LAB_00101da8;
    case 0x101e30:// 0xE push 一个紧跟在0x0E后面的立即数(DWORD),如 0x0E 0x0A 0x00 0x00 0x00 就是push 0xA,PC+5
        iVar7 = param_1->n2;// 
        uVar5 = *(undefined4 *)(lVar9 + iVar10);
        param_1->n1 = iVar11 + 5; // n1+=5
        param_1->n2 = iVar7 + 1;// n2+=1
        *(undefined4 *)(param_1->buf + (long)iVar7 * 4) = uVar5;//buf[4*prev_n2]=filed[v10]
        iVar10 = param_1->n1;//v10=n1
        goto LAB_00101da8;
    case 0x101e60://0x0D 
        param_1->n2 = param_1->n2 + -1;//n2--
        goto LAB_00101da8;
    case 0x101e70://0x0C 交换栈顶的两个元素
        FUN_00101d50(param_1);
        lVar9 = param_1->field_0x0;
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x101e80://0x0B 如果栈顶不为0则将其转变为1,反之转变为0
        iVar10 = param_1->n2;
        param_1->n2 = iVar10 + -1;//n2--
        piVar8 = (int *)(param_1->buf + (long)(iVar10 + -1) * 4);//piVar8=buf[(v10-1)*4]
        if (-1 < *piVar8)
            goto LAB_00101e9b;
        break;
    case 0x101eb0://0x0A 与上面相反,如果为1则变为0,否则变为1
        iVar10 = param_1->n2;
        param_1->n2 = iVar10 + -1;//n2--
        piVar8 = (int *)(param_1->buf + (long)(iVar10 + -1) * 4);
        if (*piVar8 != 0)// if piVar8=buf[(v10-1)*4] >= 0
        {
        LAB_00101e9b:
            param_1->n2 = iVar10;
            *piVar8 = 0;
            iVar10 = param_1->n1;
            goto LAB_00101da8;
        }
        break;
    case 0x101ee0:// 0x09 把栈顶的数字pop出来,当作索引,取出来栈上的一个数字,然后push回去,跟0x0E组合起来,是push StackBuf[op1]
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;//n2--
        param_1->n2 = iVar10;
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4);//buf[v10] as int *
        iVar10 = *(int *)(param_1->buf + (long)*piVar8 * 4);// buf[buf[v10]]
        param_1->n2 = iVar11;// 恢复n2?
        *piVar8 = iVar10;//buf[v10] = buf[buf[v10]]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x101f10:// 0x08 取出栈顶两个数字,将第一个放到栈顶的第二个所指示的位置。跟两个0x0E配合起来就组成一条指令。。StackBuf[op1]=op2
        iVar11 = param_1->n2;
        pcVar6 = param_1->buf;//v6 = buf
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;// 
        uVar5 = *(undefined4 *)(pcVar6 + (long)iVar10 * 4);//buf[v10] as qword
        param_1->n2 = iVar11 + -2;// n2-=2
        *(undefined4 *)(pcVar6 + (long)*(int *)(pcVar6 + (long)iVar10 * 4 + -4) * 4) = uVar5;//buf[buf[v10-1] as int] as qword = buf[v10] as qword
        iVar10 = param_1->n1;
        goto LAB_00101da8;
        // ^ | & 三种运算?
    case 0x101f40://0x07 取出来栈上的两个uint,相^后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        uVar3 = *(uint *)(param_1->buf + (long)iVar10 * 4);//v3=buf[v10]
        puVar1 = (uint *)(param_1->buf + (long)iVar10 * 4 + -4);//v1=buf+(v10-1)
        param_1->n2 = iVar11 + -2;
        uVar4 = *puVar1;//v4 = buf[v10-1]
        param_1->n2 = iVar10;//n2-=1
        *puVar1 = uVar4 ^ uVar3;//buf[v10-1]^=buf[v10]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x101f78://0x06 取出来栈上的两个uint,相|后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        uVar3 = *(uint *)(param_1->buf + (long)iVar10 * 4);
        puVar1 = (uint *)(param_1->buf + (long)iVar10 * 4 + -4);
        param_1->n2 = iVar11 + -2;
        uVar4 = *puVar1;
        param_1->n2 = iVar10;//n2-=1
        *puVar1 = uVar4 | uVar3;// buf[v10-1]|=buf[v10]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x101fb0://0x05 取出来栈上的两个uint,相&后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        uVar3 = *(uint *)(param_1->buf + (long)iVar10 * 4);
        puVar1 = (uint *)(param_1->buf + (long)iVar10 * 4 + -4);
        param_1->n2 = iVar11 + -2;
        uVar4 = *puVar1;
        param_1->n2 = iVar10;//n2-=1
        *puVar1 = uVar4 & uVar3;//buf[v10-1]&=buf[v10]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
        // % / 两种运算
    case 0x101fe8://0x04 取出来栈上的两个int,取模后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        iVar7 = *(int *)(param_1->buf + (long)iVar10 * 4);
        param_1->n2 = iVar11 + -2;
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4 + -4);
        iVar11 = *piVar8;
        param_1->n2 = iVar10;//n2-=1
        *piVar8 = iVar7 % iVar11;//buf[v10-1]=buf[v10]%buf[v10-1]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x102020://0x03 取出来栈上的两个int,相除后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        iVar7 = *(int *)(param_1->buf + (long)iVar10 * 4);
        param_1->n2 = iVar11 + -2;
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4 + -4);
        iVar11 = *piVar8;
        param_1->n2 = iVar10;//n2-=1
        *piVar8 = iVar7 / iVar11;//buf[v10-1]=buf[v10]%buf[v10-1]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
        // + - * 三种运算
    case 0x102058://0x02 取出来栈上的两个int,相乘后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        iVar7 = *(int *)(param_1->buf + (long)iVar10 * 4);
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4 + -4);
        param_1->n2 = iVar11 + -2;
        iVar11 = *piVar8;
        param_1->n2 = iVar10;//n2-=1
        *piVar8 = iVar11 * iVar7;//buf[v10-1]=buf[v10]*buf[v10-1]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x102090://0x01 取出来栈上的两个int,相减后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        iVar7 = *(int *)(param_1->buf + (long)iVar10 * 4);
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4 + -4);
        param_1->n2 = iVar11 + -2;
        iVar11 = *piVar8;
        param_1->n2 = iVar10;//n2--
        *piVar8 = iVar7 - iVar11;//buf[v10-1]=buf[v10]-buf[v10-1]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    case 0x1020c8://0x00 取出来栈上的两个int,相加后push回去
        iVar11 = param_1->n2;
        iVar10 = iVar11 + -1;
        param_1->n2 = iVar10;
        iVar7 = *(int *)(param_1->buf + (long)iVar10 * 4);
        piVar8 = (int *)(param_1->buf + (long)iVar10 * 4 + -4);
        param_1->n2 = iVar11 + -2;
        iVar11 = *piVar8;
        param_1->n2 = iVar10;//n2--
        *piVar8 = iVar11 + iVar7;//buf[v10-1]=buf[v10]+buf[v10-1]
        iVar10 = param_1->n1;
        goto LAB_00101da8;
    // 执行结束,返回
    case 0x102100://0x12
        uVar5 = *(undefined4 *)(lVar9 + iVar10);
        param_1->n1 = iVar11 + 5;
        return uVar5;//return [filed[v10]]
    }
    param_1->n2 = iVar10;
    *piVar8 = 1;
    iVar10 = param_1->n1;
    goto LAB_00101da8;
switchD_00101dc4_caseD_101dd0:// 0x11 类似add esp op 的操作,PC+5
    param_1->n2 = param_1->n2 + *(int *)(lVar9 + iVar10);// n2+=filed[v10]
    param_1->n1 = iVar11 + 5;
    iVar10 = iVar11 + 5;
    goto LAB_00101da8;
}


void FUN_00101d50(astruct *param_1)// 交换栈顶的两个元素

{
    int iVar1;
    undefined4 uVar2;
    undefined4 uVar3;
    int iVar4;
    char *pcVar5;

    iVar1 = param_1->n2;
    pcVar5 = param_1->buf;
    iVar4 = iVar1 + -1;
    param_1->n2 = iVar4;//n2--
    uVar2 = *(undefined4 *)(pcVar5 + (long)iVar4 * 4);
    param_1->n2 = iVar1 + -2;
    uVar3 = *(undefined4 *)(pcVar5 + (long)iVar4 * 4 + -4);
    param_1->n2 = iVar4;
    *(undefined4 *)(pcVar5 + (long)iVar4 * 4 + -4) = uVar2;//buf[v4-1]=buf[v4]
    iVar4 = param_1->n2;
    param_1->n2 = iVar4 + 1;
    *(undefined4 *)(pcVar5 + (long)iVar4 * 4) = uVar3;//buf[n2]=buf[v4-1]
    return;
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据