PCTF2016_Confused_ARM_调试记录

Posted by Mr.Be1ieVe on Friday, October 9, 2020

前言

结合书《CTF特训营》IoT篇看最佳

0x01 静态分析

指定处理器类型为ARM little-endian,不然

image-20201009103732001

正常打开之后先看看DCD部分

DCD:数据定义( Data Definition )伪指令 一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。

语法格式:

标号 DCD(或 DCDU) 表达式

DCD(或 DCDU)伪指令用于分配一片连续的字存储单元并用指定的表达式初始化。其中表达式可以为程序标号或数字表达式。 DCD 也可用 “ &” 代替。

用 DCD 分配的字存储单元是字对齐的,而用 DCDU 分配的字存储单元并不严格字对齐。

实例(STM32 启动文件):

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

来源

所以第二个即为Reset handler,即0x8000101

The reset handler contains program code that is executed as soon as the processor exits from reset. In some cases, it contains some hardware initialization.

实际地址为0x8000100

These vectors have LSB set to 1 to indicate that the exceptions handlers are to be executed with Thumb instructions

另一种判断指令集为thumb的方法

来源

这有一段指令,判断出目前是thumb指令集的

![mark](PCTF2016:Confused ARM 调试记录/bDfa164Gm2.png)

(图来自sakura博客,与confused arm无关)

mark

  • Edit->segments->change segment register value(快捷键ALT+G)

按下ALT+G,T的value 为0x0,就是指定为ARM指令集,设定为0x1,就是thumb指令集

然后在0x8000100处按C转换成code

image-20201009153839279

然后我们跟随0x8000100这个程序入口开始,一路跳转到0x8001084

image-20201009154947339

多选然后转换成hex

image-20201009155719385

0x400000000x20000000,前者是特殊功能寄存器的基地址,后者是sram的起始地址

将这些地址添加为segment,在Edit->Segments->Create segemt

image-20201009160159665

SRAM部分同上,

然后在汇编中对这地址按O

image-20201009160319480

image-20201009160429796

然后在伪代码中再按一次F5刷新

image-20201009160509472

随后在这些疑似数组的地方用如下方式进行转换

image-20201009160758788

void __fastcall __noreturn sub_8001084(int a1)
{
  int v1; // r0
  int v2; // r0

  v1 = sub_8000A00(a1);
  v2 = sub_80006A4(v1);
  sub_80007F0(v2);
  sub_8000A50(0x1C200);
  sub_8000AA8(&USART1, 0x40);
  sub_8000560(byte_2000000C, &unk_2000026C);
  while ( 1 )
  {
    if ( unk_20000000 )
    {
      sub_8000BA4(
        "Key is :0x%08x,0x%08x,0x%08x,0x%08x\r\n",
        byte_2000000C[0],
        byte_2000000C[1],
        byte_2000000C[2],
        byte_2000000C[3]);
      unk_20000000 = 0;
    }
    if ( !sub_80007E2(1073809408, 2) )
    {
      sub_800055C(byte_2000000C, &unk_2000026C);
      sub_8000248(&unk_2000001C, byte_2000031C);
      sub_8000AA8(&USART1, 64);
      sub_8000BA4(
        "Fl4g 1s :PCTF{%08x%08x%08x%08x}\r\n",
        byte_2000031C[0],
        byte_2000031C[1],
        byte_2000031C[2],
        byte_2000031C[3]);
    }
  }
}

0x02 动态调试

参考书459页进行配置

如果load hex之后提示no write permission,请按照462页的工程设置界面,将最下面的CPU DLL, Driver DLl, Dialog DLL和Parameter对照一致设置好就行

按照书上改名过后

image-20201010091446144

资料可参考这儿

==打patch为0C 4A,改成0B 4A 理解不能QwQ,后面的打patch也理解不能QwQ==

改checksum,可用以下脚本计算,来源

def check(DD):
    length=len(DD)  #求长度

    #创建一个list,将传入的str的每两个数合在一起,再求和
    list1=[]
    if(length%2==1):    #如果str长度为单数,则抛出错误
        print('[!] 数据长度有误')
    else:   
        for i in range(0, length, 2):  #range(开始,结束-1,每次加多少)  这里即0——length-1  每次循环i+2
            hex_digit=DD[i:i + 2]      #将传入的str的每两个数合在一起
            list1.append('0x'+hex_digit)    #再每个字符前+0x  但是它仍然是字符,但更便于下面通过int(list1[i], 16)转换成16进制
    print(list1)

    sum=0
    for i in range(int(length/2)):   #求和
        sum=int(list1[i], 16)+sum      #int(list1[i], 16)将16进制转换成10进制 int类型
    sum=sum%256
    sum=256-sum
    print('校验码: '+hex(sum))   #将sum和结果转换成16进制  hex(sum)

if __name__=="__main__":
    DD=input("请输入HEX文件数据记录(校验值除外):")   #input接收参数为str类型
    check(DD)

然后MDK里reload之后,run就可以了

image-20201010155940502

「真诚赞赏,手留余香」

Mr.Be1ieVe's Treasure

真诚赞赏,手留余香

使用微信扫描二维码完成支付