国赛ciscn2024-初赛-re1-asm_re(还有4题明天上)

  • 别的题明天在上,整理一下

0.精简版

第一题肯定签到,发现居然是ARM汇编代码,认真看是不可能的,看提示是XOR,那么一股CTF的味道就出来了!!
直接手动定位到ARM的异或汇编代码!–》EOR
但是定位到了两个一模一样的加密操作,就只分析一个:

MOV             W10, #0x50 ; 'P'     //mov     r10d, 0x50  ; 将 0x50 加载到 r10d
MUL             W8, W8, W10          //imul    eax, eax, r10d  ; eax = eax * r10d
ADD             W8, W8, #0x14        //add     eax, 0x14  ; eax = eax + 0x14
MOV             W10, #0x4D ; 'M'     //mov     r10d, 0x4D  ; 将 0x4D 加载到 r10d
EOR             W8, W8, W10          //xor     eax, r10d  ; eax = eax ^ r10d
ADD             W8, W8, #0x1E        //add     eax, 0x1E  ; eax = eax + 0x1E

大概率就是加密算法了,数据就特别明显了,直接挂上而且是小端序的,用chatgpt转一下:

unk_100003F10 DCB 0xD7  
DCB 0x1F
DCB    0
DCB    0
DCB 0xB7
DCB 0x21 ; !
DCB    0
...
DCB 0x20
DCB    0
DCB    0
DCB 0xC7
DCB 0x11
DCB    0
DCB    0
DCB 0x47 ; G

直接搓脚本,一把梭:

data = [215, 31, 0, 0, 183, 33, 0, 0, 71, 30, 0, 0, 39, 32, 0, 0, 231, 38, 0, 0, 
        215, 16, 0, 0, 39, 17, 0, 0, 7, 32, 0, 0, 199, 17, 0, 0, 71, 30, 0, 0, 
        23, 16, 0, 0, 23, 16, 0, 0, 247, 17, 0, 0, 7, 32, 0, 0, 55, 16, 0, 0, 
        7, 17, 0, 0, 23, 31, 0, 0, 215, 16, 0, 0, 23, 16, 0, 0, 23, 16, 0, 0, 
        103, 31, 0, 0, 23, 16, 0, 0, 199, 17, 0, 0, 199, 17, 0, 0, 23, 16, 0, 0, 
        215, 31, 0, 0, 23, 31, 0, 0, 7, 17, 0, 0, 71, 15, 0, 0, 39, 17, 0, 0, 
        55, 16, 0, 0, 71, 30, 0, 0, 55, 16, 0, 0, 215, 31, 0, 0, 7, 17, 0, 0, 
        215, 31, 0, 0, 7, 17, 0, 0, 135, 39, 0, 0]

def convert_to_hex_string(data_list):
    hex_string = ''.join(f'{byte:02X}' for byte in reversed(data_list))
    return hex_string

def hex_to_int_list(hex_str):
    int_list = [int(hex_str[i:i+8], 16) for i in range(0, len(hex_str), 8)]
    return int_list

def decode_integers_to_string(int_list):
    int_list = int_list[::-1]
    decoded_string = ''.join(chr(((value - 0x1e) ^ 0x4d) // 0x50) for value in int_list)
    return decoded_string

hex_str = convert_to_hex_string(data)
integers = hex_to_int_list(hex_str)
result_string = decode_integers_to_string(integers)

print(result_string)

成功得出flag :flag{67e9a228e45b622c2992fb5174a4f5f5}

0.详细版

0.观察文件

打开文件发现居然是IDA汇编界面的文本文件:

百度一搜发现居然是ARM架构的汇编QAQ,没学过只学过X86架构的,只能去问问chatgpt,现学现卖了!!!

1.头铁开始分析

手动百度+chatgpt-》分析汇编:

  1. 这里应该是进行赋值操作,还计算了一下长度
STP             X28, X27, [SP,#-0x10+var_10]!
STP             X29, X30, [SP,#0x10+var_s0]
ADD             X29, SP, #0x10
SUB             SP, SP, #0x100
ADRP            X8, #___stack_chk_guard_ptr@PAGE
LDR             X8, [X8,#___stack_chk_guard_ptr@PAGEOFF]
LDR             X8, [X8]
STUR            X8, [X29,#var_18]
STUR            WZR, [X29,#var_B4]
ADRL            X8, aFlagXxxxxxxxxx     ; "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
STUR            X8, [X29,#var_C0]
SUB             X0, X29, #-__dst        ; __dst
ADRL            X1, unk_100003F10       ; __src
MOV             X2, #0x98               ; __n
BL              _memcpy           复制函数, memcpy(__n,__src,__dst)

LDUR            X0, [X29,#var_C0]       ; __s
BL              _strlen           计算长度,strlen
  1. 这里进行了一些位运算和加法操作不知道作用
MOV             X8, X0
STUR            W8, [X29,#var_C4]
LDUR            W8, [X29,#var_C4]
ADD             W8, W8, #1
MOV             X9, SP
STUR            X9, [X29,#var_D0]
LSL             X9, X8, #2           这里是位移运算
ADD             X9, X9, #0xF         这里是加法运算
AND             X9, X9, #0xFFFFFFFFFFFFFFF0   这里是and运算
SUB             X10, X29, #-var_8
STUR            X9, [X10,#-0x100]
ADRP            X16, #___chkstk_darwin_ptr@PAGE
LDR             X16, [X16,#___chkstk_darwin_ptr@PAGEOFF]
BLR             X16
  1. 几乎看不懂,只能丢给chatgpt了,这里貌似进行了比较关键的运算
  • 将立即数0x50 (‘P’)加载到W10寄存器,乘以W10寄存器的数据
  • 加上0x14
  • 立即数0x4D,与W10寄存器的数据进行按位异或
LDUR            X9, [X29,#var_100]  // 从[X29-0x100]地址加载64位数据到X9寄存器
LDUR            X8, [X29,#var_C0]   // 从[X29-0xC0]地址加载64位数据到X8寄存器
LDURSW          X10, [X29,#var_DC]  // 从[X29-0xDC]地址加载32位带符号扩展的数据到X10寄存器
LDRSB           W8, [X8,X10]        // 从[X8 + X10]地址加载8位带符号扩展的数据到W8寄存器
STUR            W8, [X29,#var_E0]   // 将W8寄存器的32位数据存储到[X29-0xE0]地址
LDUR            W8, [X29,#var_E0]   // 从[X29-0xE0]地址加载32位数据到W8寄存器
MOV             W10, #0x50          // 将立即数0x50 ('P')加载到W10寄存器
MUL             W8, W8, W10         // 将W8寄存器的数据乘以W10寄存器的数据,结果存储在W8寄存器
ADD             W8, W8, #0x14       // 将W8寄存器的数据加上0x14,结果存储在W8寄存器
MOV             W10, #0x4D          // 将立即数0x4D ('M')加载到W10寄存器
EOR             W8, W8, W10         // 将W8寄存器的数据与W10寄存器的数据进行按位异或,结果存储在W8寄存器
ADD             W8, W8, #0x1E       // 将W8寄存器的数据加上0x1E,结果存储在W8寄存器
STUR            W8, [X29,#var_E4]   // 将W8寄存器的32位数据存储到[X29-0xE4]地址
LDUR            W8, [X29,#var_E4]   // 从[X29-0xE4]地址加载32位数据到W8寄存器
LDURSW          X10, [X29,#var_DC]  // 从[X29-0xDC]地址加载32位带符号扩展的数据到X10寄存器
STR             W8, [X9,X10,LSL#2]  // 将W8寄存器的数据存储到[X9 + (X10 << 2)]地址
B               loc_100003CC0       // 跳转到loc_100003CC0
  1. 这里很不理解居然有和上面的汇编算法一模一样QAQ
loc_100003D00                           // 代码标签,用于跳转
LDUR            X9, [X29,#var_100]     // 从[X29-0x100]地址加载64位数据到X9寄存器
LDUR            X8, [X29,#var_C0]      // 从[X29-0xC0]地址加载64位数据到X8寄存器
LDURSW          X10, [X29,#var_E8]     // 从[X29-0xE8]地址加载32位带符号扩展的数据到X10寄存器
LDRSB           W8, [X8,X10]           // 从[X8 + X10]地址加载8位带符号扩展的数据到W8寄存器
STUR            W8, [X29,#var_EC]      // 将W8寄存器的32位数据存储到[X29-0xEC]地址
LDUR            W8, [X29,#var_EC]      // 从[X29-0xEC]地址加载32位数据到W8寄存器
MOV             W10, #0x50             // 将立即数0x50 ('P')加载到W10寄存器
MUL             W8, W8, W10            // 将W8寄存器的数据乘以W10寄存器的数据,结果存储在W8寄存器
ADD             W8, W8, #0x14          // 将W8寄存器的数据加上0x14,结果存储在W8寄存器
MOV             W10, #0x4D             // 将立即数0x4D ('M')加载到W10寄存器
EOR             W8, W8, W10            // 将W8寄存器的数据与W10寄存器的数据进行按位异或,结果存储在W8寄存器
ADD             W8, W8, #0x1E          // 将W8寄存器的数据加上0x1E,结果存储在W8寄存器
STUR            W8, [X29,#var_F0]      // 将W8寄存器的32位数据存储到[X29-0xF0]地址
LDUR            W8, [X29,#var_F0]      // 从[X29-0xF0]地址加载32位数据到W8寄存器
LDURSW          X10, [X29,#var_E8]     // 从[X29-0xE8]地址加载32位带符号扩展的数据到X10寄存器
STR             W8, [X9,X10,LSL#2]     // 将W8寄存器的数据存储到[X9 + (X10 << 2)]地址
B               loc_100003D44           // 跳转到loc_100003D44
  1. 分析到这里就彻底无语了,根本无从下手,疯狂的盯着文本看,居然发现有提示字符串!!!
aFlagXxxxxxxxxx DCB "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}",0
                                        ; DATA XREF: _main+24↑o
asc_100003EAB DCB 0xA,0                 ; DATA XREF: _main:loc_100003D54↑o
aTheResultArray DCB "The result array matches the expected array.",0xA,0
                                        ; DATA XREF: _main:loc_100003DE0↑o
aTheResultArray_0 DCB "The result array does not match the expected array.",0xA,0
                                        ; DATA XREF: _main:loc_100003DF0↑o
; __cstring ends

找到关键字符串!!!根据字符串就可以知道哪里是判断flag的汇编位置了,继续一步步的看就好了!

2.找到提示字符串,找到判断flag的汇编代码!!


继续往上翻大概率就会有加密算法了,前面分析的代码里那个有异或运算的代码最有可能,先尝试一下!

下面就是找目标数据进行测试了!
翻了整个文本文件发现这段数据最有规律,直接拿来试试!!!

003F10                               AREA __const, DATA, READONLY
003F10                               ; ORG 0x100003F10
003F10 D7                            unk_100003F10 DCB 0xD7                  ; DATA XREF: _main+34↑o
003F11 1F                            DCB 0x1F
003F12 00                            DCB    0
003F13 00                            DCB    0
003F14 B7                            DCB 0xB7
003F15 21                            DCB 0x21 ; !
003F16 00                            DCB    0
003F17 00                            DCB    0
003F18 47                            DCB 0x47 ; G
003F19 1E                            DCB 0x1E
003F1A 00                            DCB    0
003F1B 00                            DCB    0
003F1C 27                            DCB 0x27 ; '
003F1D 20                            DCB 0x20
003F1E 00                            DCB    0
003F1F 00                            DCB    0
...

3.猜测成功真的是的,逆运算后解出个”f"

直接开始手搓脚本,chatgpt大法好!:

source_data = [0xd7 ,0x1f ,0x0 ,0x0 ,0xb7 ,0x21 ,0x0 ,0x0 ,0x47 ,0x1e ,0x0 ,0x0 ,0x27 ,0x20 ,0x0 ,0x0 ,0xe7 ,0x26 ,0x0 ,0x0 ,0xd7 ,0x10 ,0x0 ,0x0 ,0x27 ,0x11 ,0x0 ,0x0 ,0x7 ,0x20 ,0x0 ,0x0 ,0xc7 ,0x11 ,0x0 ,0x0 ,0x47 ,0x1e ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0xf7 ,0x11 ,0x0 ,0x0 ,0x7 ,0x20 ,0x0 ,0x0 ,0x37 ,0x10 ,0x0 ,0x0 ,0x7 ,0x11 ,0x0 ,0x0 ,0x17 ,0x1f ,0x0 ,0x0 ,0xd7 ,0x10 ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0x67 ,0x1f ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0xc7 ,0x11 ,0x0 ,0x0 ,0xc7 ,0x11 ,0x0 ,0x0 ,0x17 ,0x10 ,0x0 ,0x0 ,0xd7 ,0x1f ,0x0 ,0x0 ,0x17 ,0x1f ,0x0 ,0x0 ,0x7 ,0x11 ,0x0 ,0x0 ,0x47 ,0xf ,0x0 ,0x0 ,0x27 ,0x11 ,0x0 ,0x0 ,0x37 ,0x10 ,0x0 ,0x0 ,0x47 ,0x1e ,0x0 ,0x0 ,0x37 ,0x10 ,0x0 ,0x0 ,0xd7 ,0x1f ,0x0 ,0x0 ,0x7 ,0x11 ,0x0 ,0x0 ,0xd7 ,0x1f ,0x0 ,0x0 ,0x7 ,0x11 ,0x0 ,0x0 ,0x87 ,0x27 ,0x0 ,0x0]

# 将数组按小端序转换成十六进制字符串
hex_string = ''.join(f'{value:02X}' for value in source_data[::-1])

# 将十六进制字符串转换为整数列表
integers = [int(hex_string[i:i+8], 16) for i in range(0, len(hex_string), 8)]

# 反转整数列表
reversed_integers = integers[::-1]

# 解码并打印结果
for number in reversed_integers:
    character = chr(((number - 0x1E) ^ 0x4D) // 0x50)
    print(character, end="")
#flag是flag{67e9a228e45b622c2992fb5174a4f5f5}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值