2019DDCTF的一道简单逆向

昨晚躺尸的时候看到群里大佬发了一张DDCTF战况的图就起床做了一下,也就有了这个题解,RE2跟RE1其实核心思想是差不多的,只是多了一些移位操作罢了,算是弥补上个月0CTF、“西湖论剑”逆向零的突破吧
终究还是太菜了,另外一道CPP逆向也是看得头疼
——2019.4.13

0x00 查壳

一看是UPX壳,修复一下然后直接!

0x01 分析

1.载入IDA X86
  • main函数伪代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@2
  char v4; // [sp+4h] [bp-804h]@1
  char v5; // [sp+5h] [bp-803h]@1
  char v6; // [sp+404h] [bp-404h]@1
  char Dst; // [sp+405h] [bp-403h]@1

  v6 = 0;
  memset(&Dst, 0, 0x3FFu);
  v4 = 0;
  memset(&v5, 0, 0x3FFu);
  printf("please input code:");
  scanf("%s", &v6);
  sub_401000(&v6);
  if ( !strcmp(&v4, "DDCTF{reverseME}") )
  {
    printf("You've got it!!%s\n", &v4);
    result = 0;
  }
  else
  {
    printf("Try again later.\n");
    result = 0;
  }
  return result;
}
  • sub_401000函数伪代码
unsigned int __cdecl sub_401000(const char *a1)
{
  _BYTE *v1; // ecx@0
  unsigned int v2; // edi@1
  unsigned int result; // eax@1
  int v4; // ebx@2

  v2 = 0;
  result = strlen(a1);
  if ( result )
  {
    v4 = a1 - v1;
    do
    {
      *v1 = byte_402FF8[v1[v4]];
      ++v2;
      ++v1;
      result = strlen(a1);
    }
    while ( v2 < result );
  }
  return result;
}

程序大致就是将输入字符串在函数sub_401000中进行简单变换后与"DDCTF{reverseME}"比较

2.载入OD

直接在变换函数前断点



然后动态调试
伪代码中的变换就是401020~40103E的内容



核心代码无非就三条
……
movsx eax,byte ptr ds:[ebx+eax]//ds:[ebx+eax]寻址获得的数据即为将要处理的数据,并将其字扩展存入eax中
mov dl,byte ptr ds:[eax+0x402FF8]//通过eax和0x402FF8相对寄存器存址获得的字节数据存入dl中
……
mov byte ptr ds:[ecx],dl//dl数据写入数据段
……
//循环执行

所以该函数就是将输入的字符串逐个字符的hex作为偏移量在数据段中寻址获得的字符逐个拼接并写入数据段
即伪代码是

flag=""
for i in input
    flag+=ds:[hex(i)+0x402FF8]

查看地址为0x402FF8起的数据段内容

.rdata:00402FF8 ; char byte_402FF8[]
.rdata:00402FF8 byte_402FF8     db ?                    ; DATA XREF: sub_401000+24�r
.rdata:00402FF9                 align 10h
.rdata:00402FF9 _rdata          ends
.rdata:00402FF9
.data:00403000 ; Section 3. (virtual address 00003000)
.data:00403000 ; Virtual size                  : 000003E4 (    996.)
.data:00403000 ; Section size in file          : 00000200 (    512.)
.data:00403000 ; Offset to raw data for section: 00001600
.data:00403000 ; Flags C0000040: Data Readable Writable
.data:00403000 ; Alignment     : default
.data:00403000 ; ===========================================================================
.data:00403000
.data:00403000 ; Segment type: Pure data
.data:00403000 ; Segment permissions: Read/Write
.data:00403000 _data           segment para public 'DATA' use32
.data:00403000                 assume cs:_data
.data:00403000                 ;org 403000h
.data:00403000 ___security_cookie dd 0BB40E64Eh        ; DATA XREF: _main+6�r
.data:00403000                                         ; __security_check_cookie(x)�r ...
.data:00403004 dword_403004    dd 44BF19B1h            ; DATA XREF: ___report_gsfailure+B0�r
.data:00403004                                         ; ___security_init_cookie+2B�w ...
.data:00403008                 db 0FFh
.data:00403009                 db 0FFh
.data:0040300A                 db 0FFh
.data:0040300B                 db 0FFh
.data:0040300C                 db 0FFh
.data:0040300D                 db 0FFh
.data:0040300E                 db 0FFh
.data:0040300F                 db 0FFh
.data:00403010 dword_403010    dd 0FFFFFFFEh           ; DATA XREF: .text:004013E2�r
.data:00403014 dword_403014    dd 1                    ; DATA XREF: .text:004013C8�r
.data:00403018 aZyxwvutsrqponm db '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>'
.data:00403018                 db '=<;:9876543210/.-,+*)(',27h,'&%$#"! ',0
.data:00403078 ; int argc

注意到0x403018起定义了这么一段字符

~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>'=<;:9876543210/.-,+*)(',27h,'&%$#"!

到此就可以解题了,直接逆算法遍历目标字符串获得输入

dst="DDCTF{reverseME}"
str="~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>'=<;:9876543210/.-,+*)(',27h,'&%$#\"!"
flag=""
for i in dst:
    index=str.find(i)
    flag+=chr(index+(0x403018-0x402FF8))
print("flag:"+flag)

获得flag是ZZ[JX#,9(9,+9QY!


最后包裹上DDCTF{}提交即可

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容