0


Reverse入门[不断记录]

文章目录


前言

心血来潮,想接触点Reverse,感受下Reverse,于是从CTF的简单题目中慢慢入门


提示:以下是本篇文章正文内容,下面案例可供参考

一、[SWPUCTF 2021 新生赛]re1

1、工具:IDA
直接使用IDA将exe反编译,得到一堆代码。
在这里插入图片描述

使用Ctrl+X,查看编译流程,然后使用F5,查看代码。

int __cdecl main(int argc,constchar**argv,constchar**envp){char Str2[1008];// [rsp+20h] [rbp-60h] BYREFchar Str1[1000];// [rsp+410h] [rbp+390h] BYREFint i;// [rsp+7FCh] [rbp+77Ch]_main();strcpy(Str2,"{34sy_r3v3rs3}");printf("please put your flag:");scanf("%s", Str1);for( i =0; i <=665;++i ){if( Str1[i]==101)
      Str1[i]=51;}for( i =0; i <=665;++i ){if( Str1[i]==97)
      Str1[i]=52;}if(strcmp(Str1, Str2))printf("you are wrong,see again!");elseprintf("you are right!");system("pause");return0;}

将输入的字符,ascii为101的变成51,97的变成52,然后与str2对比,一致则成功。

s ='{34sy_r3v3rs3}'
r =''for i in s:iford(i)==51:
        r +=chr(101)eliford(i)==52:
        r +=chr(97)else:
        r += i
print(r)

得到flag

二、[SWPUCTF 2021 新生赛]re2

int __cdecl main(int argc,constchar**argv,constchar**envp){char Str2[64];// [rsp+20h] [rbp-90h] BYREFchar Str[68];// [rsp+60h] [rbp-50h] BYREFint v7;// [rsp+A8h] [rbp-8h]int i;// [rsp+ACh] [rbp-4h]_main();strcpy(Str2,"ylqq]aycqyp{");printf(Format);gets(Str);
  v7 =strlen(Str);for( i =0; i < v7;++i ){if((Str[i]<=96|| Str[i]>98)&&(Str[i]<=64|| Str[i]>66))
      Str[i]-=2;else
      Str[i]+=24;}if(strcmp(Str, Str2))printf(asc_404024);elseprintf(aBingo);system("pause");return0;}
s ='ylqq]aycqyp{'
l =[]for i in s:
    l.append(ord(i))# print(l)
l =[121,108,113,113,93,97,121,99,113,121,112,123]
r =''for i in l:if(i <=94or i >96)and(i <=62or i >64):
        r +=chr(i +2)else:
        r +=chr(i -24)print(r)

得到的结果进行caser,并且猜一下,得到{nss_caesar}

三、[GFCTF 2021]wordy[花指令]

  1. 花指令实质就是一串垃圾指令,它与程序本身的功能无关,并不影响程序本身的逻辑。在软件保护中,花指令被作为一种手段来增加静态分析的难度,花指令也可以被用在病毒或木马上,通过加入花指令改变程序的特征码,躲避杀软的扫描,从而达到免杀的目的。
  2. 花指令是让反编译器无法反编译起到混淆租用的指令,一般最常见的就是在机器码中加入 E8,E8 加入后会将汇编代码改变为 CALL,而后续的机器码代表的东西是没有意义的,不是一个函数,所以 CALL 之后反编译器无法识别。

在这里插入图片描述
在这里插入图片描述

存在大量jmp跳转,导致程序无法正常编译,尝试将跳转nop掉,即将其转换成空指令。

startaddr =0x1135
endaddr =0x3100for i inrange(startaddr,endaddr):if get_wide_byte(i)==0xEB:if get_wide_byte(i+1)==0xFF:
            patch_byte(i,0x90)print("[+] Addr {} is patched".format(hex(i)))

起始地址是main函数的0x1135到结束,通过遍历byte,判断是否和EB FF,即jmp的机械码,是则改成90,即nop。
在这里插入图片描述
看到flag为GFCTF{u_are2wordy}

四、[NSSRound#3 Team]jump_by_jump[花指令]

  1. 先找主函数入口,即main在这里插入图片描述

可以看到0041188C处有call,并且爆红,可以判断为花指令,因此要消除即变成nop,选中41188C,按快捷键D,将其转换为数据。

在这里插入图片描述

然后将0E8h改成0x90即nop机器码

在这里插入图片描述

快捷键C,将数据再次转换成指令,并将下面黄色的部分依次使用C转换成指令。

在这里插入图片描述

最后往上选中main入口,快捷键P生成函数,然后F5,获得函数代码。

int __cdecl main_0(int argc,constchar**argv,constchar**envp){int i;// [esp+D0h] [ebp-2Ch]char v5[28];// [esp+DCh] [ebp-20h] BYREFstrcpy(v5,"NSSCTF{Jump_b9_jump!}");for( i =0; i <21;++i )
    v5[i]=(v5[i]+ v5[(i * i +123)%21])%128;sub_4110CD("%s",(char)v5);return0;}

发现flag根本没被加密,直接开始Shift+F12就可以看到字符串。

五、[NSSRound#3 Team]jump_by_jump_revenge[花指令]

在这里插入图片描述

跟上面一样,将爆红那里改成空指令,P+F5得到伪代码。

int __cdecl main_0(int argc,constchar**argv,constchar**envp){int i;// [esp+D0h] [ebp-40h]char Str1[36];// [esp+E8h] [ebp-28h] BYREFsub_411037("%s",(char)Str1);for( i =0; i <29;++i )
    Str1[i]=(Str1[i]+ Str1[(i * i +123)%21])%96+32;if(!j_strcmp(Str1,"~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*"))puts("right!");elseputs("nope!");return0;}

将flag打乱了,并且进行了变换,逆向解密。

a =['~','4','G','~','M',':','=','W','V','7','i','X',',','z','l','V','i','G','m','u','4','?','h','J','0','H','-','Q','*']for i inrange(28,-1,-1):
    k =(i * i +123)%21for j inrange(5):
        x =(ord(a[i])-32+ j *96-ord(a[k]))if33<= x <=126:
            a[i]=chr(x)breakprint("".join(a))

六、[WUSTCTF 2020]level2[UPX脱壳]

  1. 脱壳,就是说把程序的外壳给脱掉,从而能够看到真正的程序,在程序运行时,首先是壳取得控制权并对程序进行压缩,从而隐藏程序真正的OEP(原始的程序入口点),一般丢进IDX后,函数特别少,是加壳了。
  2. 程序的脱壳一般总体是三个步骤:
  1. 找到OEP,程序运行壳代码执行完后会跳转到真正的OEP
  2. 抓到内存文件,将新得到的源文件保存,可从头到后复制
  3. 对PE文件进行修复

萌新,手动脱壳不是很现实,一些脱壳工具链接:
UPX脱壳工具

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、[HUBUCTF 2022 新生赛]simple_RE

int __cdecl main(int argc,constchar**argv,constchar**envp){int v4;// [rsp+24h] [rbp-44h] BYREFvoid*Buf1;// [rsp+28h] [rbp-40h] BYREFchar v6[56];// [rsp+30h] [rbp-38h] BYREFsub_401770(argc, argv, envp);printf("please input the flag:");scanf("%s", v6);
  Buf1 =0i64;sub_401570(v6,&Buf1,&v4);if(!memcmp(Buf1, a5mc58bphliax7j, v4))printf("\nsuccess!");elseprintf("\nfailed!");if( Buf1 )free(Buf1);return0;}

输入的v6经过sub_401570()函数加密与a5mc58bphliax7j比较,一致则成功,a5mc58bphliax7j的值为5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==,有点像是base64。

在这里插入图片描述

但是下面好像还有一串字符串,不知道干什么的,看了下加密函数。

在这里插入图片描述

好像加密跟下面的字符串有关,正常的base64也解密不出来,可能是base64换表。

在这里插入图片描述

七、[SWPUCTF 2021 新生赛]easyapp

发现PK头,直接改成zip后缀,解压得到一个apk安卓,反编译,得:
在这里插入图片描述
Encode类:

packagecom.example.ilililililil;publicclassEncoder{privateint key =123456789;publicStringencode(String paramString){StringBuilder localStringBuilder =newStringBuilder();
    paramString = paramString.toCharArray();int i = paramString.length;for(int j =0; j < i; j++)
      localStringBuilder.append((char)(paramString[j]^this.key));return localStringBuilder.toString();}}
public/* synthetic */void lambda$onCreate$0$MainActivity(finalEditText editText,View v){System.out.println(encoder.encode(editText.getText().toString()));if(encoder.encode(editText.getText().toString()).equals("棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌")){Toast.makeText(this,"YES",0).show();}else{Toast.makeText(this,"NO",0).show();}}

MainActivity类:

packagecom.example.ilililililil;importjava.lang.reflect.Field;publicclassMainActlvity{publicMainActlvity(){try{Field localField =Encoder.class.getDeclaredField("key");
      localField.setAccessible(true);
      localField.set(MainActivity.encoder,Integer.valueOf(987654321));}catch(NoSuchFieldException localNoSuchFieldException){}catch(IllegalAccessException localIllegalAccessException){}
    localIllegalAccessException.printStackTrace();}}

可以知道key变成了987654321

所以exp为:

code ='棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌'
key =987654321
flag =""for i in code:
    flag +=chr((ord(i)^ key)%128)print(flag)

得到flag NSSCTF{apkYYDS}

八、[鹏城杯 2022]baby_re[apk反编译+JNI]

在这里插入图片描述
反编译得到关键代码:

privatestaticfinalvoid onCreate$lambda-0(MainActivity paramMainActivity,int[] paramArrayOfInt,View paramView){Intrinsics.checkNotNullParameter(paramMainActivity,"this$0");Intrinsics.checkNotNullParameter(paramArrayOfInt,"$c");
    paramView =((EditText)paramMainActivity._$_findCachedViewById(R.id.input)).getText().toString().chars().toArray();Intrinsics.checkNotNullExpressionValue(paramView,"flag.toArray()");if(Arrays.equals(paramMainActivity.baby_xor(paramView), paramArrayOfInt))Toast.makeText((Context)paramMainActivity,(CharSequence)"Success",1).show();elseToast.makeText((Context)paramMainActivity,(CharSequence)"Failed",0).show();}protectedvoidonCreate(Bundle paramBundle){super.onCreate(paramBundle);ActivityMainBinding localActivityMainBinding =ActivityMainBinding.inflate(getLayoutInflater());Intrinsics.checkNotNullExpressionValue(localActivityMainBinding,"inflate(layoutInflater)");this.binding = localActivityMainBinding;
    paramBundle = localActivityMainBinding;if(localActivityMainBinding ==null){Intrinsics.throwUninitializedPropertyAccessException("binding");
      paramBundle =null;}setContentView((View)paramBundle.getRoot());((Button)_$_findCachedViewById(R.id.btn)).setOnClickListener(newMainActivity..ExternalSyntheticLambda0(this,newint[]{119,9,40,44,106,83,126,123,33,87,113,123,112,93,125,127,41,82,44,127,39,3,126,125,119,87,47,125,33,6,44,127,112,0,126,123,115,24}));}

flag转成了数组,进行baby_xor异或,要等于{ 119, 9, 40, 44, 106, 83, 126, 123, 33, 87, 113, 123, 112, 93, 125, 127, 41, 82, 44, 127, 39, 3, 126, 125, 119, 87, 47, 125, 33, 6, 44, 127, 112, 0, 126, 123, 115, 24 },在反编译的函数中找不到baby_xor,它还给了so文件,放入IDA,会发现存在babyxor函数。
在这里插入图片描述

__int64 __fastcall Java_com_example_createso_MainActivity_baby_1xor(__int64 a1, __int64 a2, __int64 a3){int i;// [rsp+14h] [rbp-2Ch]
  __int64 v5;// [rsp+18h] [rbp-28h]unsignedint v6;// [rsp+24h] [rbp-1Ch]

  v6 = _JNIEnv::GetArrayLength(a1, a3);
  v5 = _JNIEnv::GetIntArrayElements(a1, a3,0LL);for( i =0; i <(int)v6;++i )*(_DWORD *)(v5 +4LL* i)^= key[i %4];
  _JNIEnv::SetIntArrayRegion(a1, a3,0LL, v6, v5);return a3;}

_DWORD *hide_key(void){
  _DWORD *result;// rax

  result = key;
  key[0]^=0x47u;
  key[1]^=0x32u;
  key[2]^=0x11u;
  key[3]^=0x12u;return result;}

这里就是先将key异或变一下,然后与key[i%4]做异或。

在这里插入图片描述

发现key的初始值 0x56 0x57 0x58 0x59

from Crypto.Util.number import long_to_bytes

l =[119,9,40,44,106,83,126,123,33,87,113,123,112,93,125,127,41,82,44,127,39,3,126,125,119,87,47,125,33,6,44,127,112,0,126,123,115,24]
key =[0x56,0x57,0x58,0x59]
key[0]^=0x47
key[1]^=0x32
key[2]^=0x11
key[3]^=0x12
flag =''for i inrange(len(l)):
    flag +=chr(l[i]^ key[i %4])print(flag)

得到flag

九、[GWCTF 2019]babyvm[VMre]

主函数获取输入:
在这里插入图片描述
主要功能在sub_CD1:
在这里插入图片描述
在这里插入图片描述

函数定义了操作码的功能,可看成是操作码表,202060地址存放操作码,可理解成密文,qword_2022A8存放输入的字符串,其余九是操作码代表的功能,要通过语句推断功能代表的语句,还原程序流程。

0XF1
在这里插入图片描述

多个分支,并且都是赋值,推断是mov操作,根据0xE1等分直情况不同,进行不同的表达式,0XE1:mov R0 flag 0XE2:mov R1 flag以此类推

0xF2
在这里插入图片描述

xor操作,R0=R0^R1

0xF5
在这里插入图片描述

读取长度为21的flag

0xF4
在这里插入图片描述
0xF7
在这里插入图片描述

mul乘法操作,R0=R0*R3

0xF8
在这里插入图片描述

swap交换指令操作,swap R0 R1

0xF6
在这里插入图片描述

线性运算 R0=R2+2R1+3R0

知道所有的操作码的含义后,获取密文操作码,从0x202060到0x20229结束,然后翻译操作码

import binascii
from pwn import*
fd =open("babyvm","rb")
arr =[]
offset =0x2060while offset <=0x229e:
    fd.seek(offset)
    fr = fd.read(1)
    arr.append(int(binascii.b2a_hex(fr).decode('utf-8'),16))
    offset +=1# print(arr, len(arr))
result =""
i =0while i <575:if arr[i]==0xf1:if arr[i +1]==0xE1:
            result +="{0} mov R0 flag[{1}]\n".format(i, arr[i +2])elif arr[i +1]==0xE2:
            result +="{0} mov R1 flag[{1}]\n".format(i, arr[i +2])elif arr[i +1]==0xE3:
            result +="{0} mov R2 flag[{1}]\n".format(i, arr[i +2])elif arr[i +1]==0xE4:
            result +="{0} mov flag[{1}] R0\n".format(i, arr[i +2])elif arr[i +1]==0xE5:
            result +="{0} mov R3 flag[{1}]\n".format(i, arr[i +2])elif arr[i +1]==0xE7:
            result +="{0} mov flag[{1}] R1\n".format(i, arr[i +2])
        i = i +6elif arr[i]==0xf2:
        result +="{0} xor R0 R1\n".format(i)
        i +=1elif arr[i]==0xf5:
        result +="{0} read flag 21\n".format(i)
        i +=1elif arr[i]==0xf4:
        i +=1elif arr[i]==0xf7:
        result +="{0} mul R0 R3\n".format(i)
        i +=1elif arr[i]==0xf8:
        result +="{0} swap R0 R1\n".format(i)
        i +=1elif arr[i]==0xf6:
        result +="{0} mov R0 R2+2*R1+3*R0\n".format(i)
        i +=1else:
        i +=1withopen("babyvm.txt","a+")as tr:
    tr.write(result)
    tr.close()

得到:

0read flag 211 mov R0 flag[0]7 xor R0 R1
8 mov flag[32] R0
14 mov R0 flag[1]20 xor R0 R1
21 mov flag[33] R0
27 mov R0 flag[2]33 xor R0 R1
34 mov flag[34] R0
40 mov R0 flag[3]46 xor R0 R1
47 mov flag[35] R0
53 mov R0 flag[4]59 xor R0 R1
60 mov flag[36] R0
66 mov R0 flag[5]72 xor R0 R1
73 mov flag[37] R0
79 mov R0 flag[6]85 xor R0 R1
86 mov flag[38] R0
92 mov R0 flag[7]98 xor R0 R1
99 mov flag[39] R0
105 mov R0 flag[8]111 xor R0 R1
112 mov flag[40] R0
118 mov R0 flag[9]124 xor R0 R1
125 mov flag[41] R0
131 mov R0 flag[10]137 xor R0 R1
138 mov flag[42] R0
144 mov R0 flag[11]150 xor R0 R1
151 mov flag[43] R0
157 mov R0 flag[12]163 xor R0 R1
164 mov flag[44] R0
170 mov R0 flag[13]176 xor R0 R1
177 mov flag[45] R0
183 mov R0 flag[14]189 xor R0 R1
190 mov flag[46] R0
196 mov R0 flag[15]202 xor R0 R1
203 mov flag[47] R0
209 mov R0 flag[16]215 xor R0 R1
216 mov flag[48] R0
222 mov R0 flag[17]228 xor R0 R1
229 mov flag[49] R0
235 mov R0 flag[18]241 xor R0 R1
242 mov flag[50] R0
248 mov R0 flag[19]254 xor R0 R1
255 mov flag[51] R0
288read flag 21289 mov R0 flag[0]295 mov R1 flag[1]301 xor R0 R1
302 mov flag[0] R0
308 mov R0 flag[1]314 mov R1 flag[2]320 xor R0 R1
321 mov flag[1] R0
327 mov R0 flag[2]333 mov R1 flag[3]339 xor R0 R1
340 mov flag[2] R0
346 mov R0 flag[3]352 mov R1 flag[4]358 xor R0 R1
359 mov flag[3] R0
365 mov R0 flag[4]371 mov R1 flag[5]377 xor R0 R1
378 mov flag[4] R0
384 mov R0 flag[5]390 mov R1 flag[6]396 xor R0 R1
397 mov flag[5] R0
403 mov R0 flag[6]409 mov R1 flag[7]415 mov R2 flag[8]421 mov R3 flag[12]427 mov R0 R2+2*R1+3*R0
428 mul R0 R3
429 mov flag[6] R0
435 mov R0 flag[7]441 mov R1 flag[8]447 mov R2 flag[9]453 mov R3 flag[12]459 mov R0 R2+2*R1+3*R0
460 mul R0 R3
461 mov flag[7] R0
467 mov R0 flag[8]473 mov R1 flag[9]479 mov R2 flag[10]485 mov R3 flag[12]491 mov R0 R2+2*R1+3*R0
492 mul R0 R3
493 mov flag[8] R0
499 mov R0 flag[13]505 mov R1 flag[19]511 swap R0 R1
512 mov flag[13] R0
518 mov flag[19] R1
524 mov R0 flag[14]530 mov R1 flag[18]536 swap R0 R1
537 mov flag[14] R0
543 mov flag[18] R1
549 mov R0 flag[15]555 mov R1 flag[17]561 swap R0 R1
562 mov flag[15] R0
568 mov flag[17] R1

有两端read flag操作,但是第一段flag[34]等等,flag长度只有21,所有第二段是正确的,分析第二段

288read flag 21289 mov R0 flag[0]295 mov R1 flag[1]301 xor R0 R1
302 mov flag[0] R0          //flag[0]=flag[0]^flag[1]308 mov R0 flag[1]314 mov R1 flag[2]320 xor R0 R1
321 mov flag[1] R0          //flag[1]=flag[1]^flag[2]327 mov R0 flag[2]333 mov R1 flag[3]339 xor R0 R1
340 mov flag[2] R0          flag[2]=flag[2]^flag[3]346 mov R0 flag[3]352 mov R1 flag[4]358 xor R0 R1
359 mov flag[3] R0      //flag[3]=flag[3]^flag[4]365 mov R0 flag[4]371 mov R1 flag[5]377 xor R0 R1
378 mov flag[4] R0      //flag[4]=flag[4]^flag[5]384 mov R0 flag[5]390 mov R1 flag[6]396 xor R0 R1
397 mov flag[5] R0      //flag[5]=flag[5]^flag[6]403 mov R0 flag[6]409 mov R1 flag[7]415 mov R2 flag[8]421 mov R3 flag[12]427 mov R0 R2+2*R1+3*R0
428 mul R0 R3           //flag[6]=FLAG[8]+2*FLAG[7]+3*FLAG[6]*FLAG[12]429 mov flag[6] R0
435 mov R0 flag[7]441 mov R1 flag[8]447 mov R2 flag[9]453 mov R3 flag[12]459 mov R0 R2+2*R1+3*R0
460 mul R0 R3           //flag[7]=flag[9]+2*flag[8]+3*flag[7]*flag[12]461 mov flag[7] R0
467 mov R0 flag[8]473 mov R1 flag[9]479 mov R2 flag[10]485 mov R3 flag[12]491 mov R0 R2+2*R1+3*R0
492 mul R0 R3
493 mov flag[8] R0       //flag[8]=(flag[10]+2*flag[9]+3*flag[8])*flag[12]499 mov R0 flag[13]505 mov R1 flag[19]511 swap R0 R1          //swap(flag[13],flag[19])512 mov flag[13] R0
518 mov flag[19] R1
524 mov R0 flag[14]530 mov R1 flag[18]536 swap R0 R1      //swap(flag[14],flag[18])537 mov flag[14] R0
543 mov flag[18] R1
549 mov R0 flag[15]555 mov R1 flag[17]561 swap R0 R1      //swap(flag[15],flag[17])562 mov flag[15] R0
568 mov flag[17] R1

程序的操作大致为:

flag=''for i inrange(6)::
    flag[i]=flag[i]^flag[i+1]
    
flag[6]=(flag[8]+2*flag[7]+3*flag[6])*flag[12]
flag[7]=(flag[9]+2*flag[8]+3*flag[7])*flag[12]
flag[8]=(flag[10]+2*flag[9]+3*flag[8])*flag[12]
swap(flag[13],flag[19])
swap(flag[14],flag[18])
swap(flag[15],flag[17])

在这里插入图片描述

题目真正的check

还原脚本

from pwn import*
re =[]
fd =open("babyvm","rb")
offset =0x2020while offset <0x2034:
    fd.seek(offset)
    fr = fd.read(1)
    re.append(int(binascii.b2a_hex(fr).decode('utf-8'),16))
    offset +=1# print(re,len(re))
flag =[]for i inrange(20):
    flag.append(0)
flag[11]= re[11]
flag[12]= re[12]
flag[13]= re[19]
flag[14]= re[18]
flag[15]= re[17]
flag[16]= re[16]
flag[17]= re[15]
flag[18]= re[14]
flag[19]= re[13]
flag[9]= re[9]
flag[10]= re[10]for i inrange(128):if re[8]==((i *3+ flag[9]*2+ flag[10])* flag[12])&0xff:
        flag[8]= i
        for j inrange(128):if re[7]==((j *3+ flag[8]*2+ flag[9])* flag[12])&0xff:
                flag[7]= j
                for k inrange(128):if re[6]==((k *3+ flag[7]*2+ flag[8])* flag[12])&0xff:
                        flag[6]= k
flag[5]= re[5]^ flag[6]
flag[4]= re[4]^ flag[5]
flag[3]= re[3]^ flag[4]
flag[2]= re[2]^ flag[3]
flag[1]= re[1]^ flag[2]
flag[0]= re[0]^ flag[1]
FLAG =""for i in flag:
    FLAG +=chr(i)print(FLAG)

得到flag

总结一下VMre的解法步骤:
1.根据函数获取操作码表,操作码表中对应的操作,还原程序流程。
2.根据程序流程获得程序的算法。
3.获取flag存放位置并获得加密数据,根据算法还原。

十、[NISACTF 2022]鸣神的国土

.file    "test.c".text
    .section    .rodata
.LC0:.string    "%s".LC1:.string    "YES,you get the flag".LC2:.string    "NO,error".text
    .globl    main
    .type    main, @function
main:.LFB6:.cfi_startproc
    endbr64
    pushq    %rbp
    .cfi_def_cfa_offset 16.cfi_offset 6,-16
    movq    %rsp,%rbp
    .cfi_def_cfa_register 6
    pushq    %rbx
    subq    $216,%rsp
    .cfi_offset 3,-24
    movq    %fs:40,%rax
    movq    %rax,-24(%rbp)
    xorl    %eax,%eax
    movabsq    $7158324656262427505,%rax
    movabsq    $7163901470557426799,%rdx
    movq    %rax,-208(%rbp)
    movq    %rdx,-200(%rbp)
    movabsq    $3619001219890117209,%rax
    movabsq    $5780770822738496110,%rdx
    movq    %rax,-192(%rbp)
    movq    %rdx,-184(%rbp)
    movabsq    $3838605427404404553,%rax
    movabsq    $4427116830602054234,%rdx
    movq    %rax,-176(%rbp)
    movq    %rdx,-168(%rbp)
    movb    $0,-160(%rbp)
    movl    $0,-212(%rbp)
    leaq    -80(%rbp),%rax
    movq    %rax,%rsi
    leaq    .LC0(%rip),%rdi
    movl    $0,%eax
    call    __isoc99_scanf@PLT
    movl    $0,-220(%rbp)
    jmp    .L2
.L15:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    cmpb    $64,%al
    jle    .L3
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    cmpb    $90,%al
    jle    .L4
.L3:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    cmpb    $96,%al
    jle    .L5
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    cmpb    $122,%al
    jle    .L6
.L5:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%edx
    movl    -220(%rbp),%eax
    cltq
    movb    %dl,-144(%rbp,%rax)
    jmp    .L11
.L6:
    movl    $97,-216(%rbp)
    jmp    .L8
.L10:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    movsbl    %al,%eax
    leal    -84(%rax),%edx
    movslq    %edx,%rax
    imulq    $1321528399,%rax,%rax
    shrq    $32,%rax
    movl    %eax,%ecx
    sarl    $3,%ecx
    movl    %edx,%eax
    sarl    $31,%eax
    subl    %eax,%ecx
    movl    %ecx,%eax
    imull    $26,%eax,%eax
    subl    %eax,%edx
    movl    %edx,%eax
    addl    $97,%eax
    cmpl    %eax,-216(%rbp)
    jne    .L9
    movl    -216(%rbp),%eax
    movl    %eax,%edx
    movl    -220(%rbp),%eax
    cltq
    movb    %dl,-144(%rbp,%rax).L9:
    addl    $1,-216(%rbp).L8:
    cmpl    $122,-216(%rbp)
    jle    .L10
    jmp    .L11
.L4:
    movl    $65,-216(%rbp)
    jmp    .L12
.L14:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -80(%rbp,%rax),%eax
    movsbl    %al,%eax
    leal    -52(%rax),%edx
    movslq    %edx,%rax
    imulq    $1321528399,%rax,%rax
    shrq    $32,%rax
    movl    %eax,%ecx
    sarl    $3,%ecx
    movl    %edx,%eax
    sarl    $31,%eax
    subl    %eax,%ecx
    movl    %ecx,%eax
    imull    $26,%eax,%eax
    subl    %eax,%edx
    movl    %edx,%eax
    addl    $65,%eax
    cmpl    %eax,-216(%rbp)
    jne    .L13
    movl    -216(%rbp),%eax
    movl    %eax,%edx
    movl    -220(%rbp),%eax
    cltq
    movb    %dl,-144(%rbp,%rax).L13:
    addl    $1,-216(%rbp).L12:
    cmpl    $90,-216(%rbp)
    jle    .L14
.L11:
    addl    $1,-220(%rbp).L2:
    movl    -220(%rbp),%eax
    movslq    %eax,%rbx
    leaq    -80(%rbp),%rax
    movq    %rax,%rdi
    call    strlen@PLT
    cmpq    %rax,%rbx
    jb    .L15
    movl    $0,-220(%rbp)
    jmp    .L16
.L18:
    movl    -220(%rbp),%eax
    cltq
    movzbl    -208(%rbp,%rax),%edx
    movl    -220(%rbp),%eax
    cltq
    movzbl    -144(%rbp,%rax),%eax
    cmpb    %al,%dl
    jne    .L17
    addl    $1,-212(%rbp).L17:
    addl    $1,-220(%rbp).L16:
    movl    -220(%rbp),%eax
    movslq    %eax,%rbx
    leaq    -80(%rbp),%rax
    movq    %rax,%rdi
    call    strlen@PLT
    cmpq    %rax,%rbx
    jb    .L18
    movl    -212(%rbp),%eax
    movslq    %eax,%rbx
    leaq    -208(%rbp),%rax
    movq    %rax,%rdi
    call    strlen@PLT
    cmpq    %rax,%rbx
    jne    .L19
    leaq    .LC1(%rip),%rdi
    call    puts@PLT
    jmp    .L20
.L19:
    leaq    .LC2(%rip),%rdi
    call    puts@PLT
.L20:
    movl    $0,%eax
    movq    -24(%rbp),%rsi
    xorq    %fs:40,%rsi
    je    .L22
    call    __stack_chk_fail@PLT
.L22:
    addq    $216,%rsp
    popq    %rbx
    popq    %rbp
    .cfi_def_cfa 7,8
    ret
    .cfi_endproc
.LFE6:.size    main,.-main
    .ident    "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0".section    .note.GNU-stack,"",@progbits
    .section    .note.gnu.property,"a".align 8.long1f-0f.long4f-1f.long50:.string     "GNU"1:.align 8.long0xc0000002.long3f-2f2:.long0x33:.align 84:

直接给GNU代码,可以使用as命令将汇编代码编译为二进制代码,让再用gcc编译成程序。

在这里插入图片描述

int __cdecl main(int argc,constchar**argv,constchar**envp){int i;// [rsp+4h] [rbp-DCh]int l;// [rsp+4h] [rbp-DCh]int k;// [rsp+8h] [rbp-D8h]int j;// [rsp+8h] [rbp-D8h]int v8;// [rsp+Ch] [rbp-D4h]char v9[128];// [rsp+10h] [rbp-D0h] BYREFchar s[56];// [rsp+90h] [rbp-50h] BYREFunsigned __int64 v11;// [rsp+C8h] [rbp-18h]

  v11 =__readfsqword(0x28u);strcpy(v9,"q3q3YzWcoTyvnJkcYzAioF92nJEyol9PIwSeLwE5ZJ03MGp=");
  v8 =0;__isoc99_scanf(&unk_2004, s);for( i =0; i <strlen(s);++i ){if( s[i]>64&& s[i]<=90){for( j =65; j <=90;++j ){if( j ==(s[i]-52)%26+65)
          v9[i +64]= j;}}elseif( s[i]>96&& s[i]<=122){for( k =97; k <=122;++k ){if( k ==(s[i]-84)%26+97)
          v9[i +64]= k;}}else{
      v9[i +64]= s[i];}}for( l =0; l <strlen(s);++l ){if( v9[l]== v9[l +64])++v8;}if( v8 ==strlen(v9))puts("YES,you get the flag");elseputs("NO,error");return0;}

在这里插入图片描述

十一、[广东强网杯 2021 个人组]goodpy

10 LOAD_CONST               0(-1)3 LOAD_CONST               1(None)6 IMPORT_NAME              0(os)9 STORE_NAME               0(os)412 LOAD_CONST               2(0)15 STORE_NAME               1(a)518 LOAD_NAME                2(input)21 CALL_FUNCTION            024 STORE_NAME               3(flag)627 SETUP_LOOP              36(to 66)30 LOAD_NAME                4(range)33 LOAD_NAME                5(len)36 LOAD_NAME                3(flag)39 CALL_FUNCTION            142 CALL_FUNCTION            145 GET_ITER            
        >>46 FOR_ITER                16(to 65)49 STORE_NAME               6(i)752 LOAD_NAME                1(a)55 LOAD_CONST               3(1)58 INPLACE_ADD         
             59 STORE_NAME               1(a)62 JUMP_ABSOLUTE           46>>65 POP_BLOCK           

  9>>66 LOAD_NAME                1(a)69 LOAD_CONST               4(32)72 COMPARE_OP               3(!=)75 POP_JUMP_IF_FALSE       931078 LOAD_CONST               5('error')81 PRINT_ITEM          
             82 PRINT_NEWLINE       

 1183 LOAD_NAME                7(exit)86 CALL_FUNCTION            089 POP_TOP             
             90 JUMP_FORWARD             0(to 93)13>>93 LOAD_NAME                3(flag)96 LOAD_CONST               2(0)99 BINARY_SUBSCR       
            100 LOAD_CONST               6('f')103 COMPARE_OP               3(!=)106 POP_JUMP_IF_TRUE       189109 LOAD_NAME                3(flag)112 LOAD_CONST               3(1)115 BINARY_SUBSCR       
            116 LOAD_CONST               7('l')119 COMPARE_OP               3(!=)122 POP_JUMP_IF_TRUE       189125 LOAD_NAME                3(flag)128 LOAD_CONST               8(2)131 BINARY_SUBSCR       
            132 LOAD_CONST               9('a')135 COMPARE_OP               3(!=)138 POP_JUMP_IF_TRUE       189141 LOAD_NAME                3(flag)144 LOAD_CONST              10(3)147 BINARY_SUBSCR       
            148 LOAD_CONST              11('g')151 COMPARE_OP               3(!=)154 POP_JUMP_IF_TRUE       189157 LOAD_NAME                3(flag)160 LOAD_CONST              12(4)163 BINARY_SUBSCR       
            164 LOAD_CONST              13('{')167 COMPARE_OP               3(!=)170 POP_JUMP_IF_TRUE       189173 LOAD_NAME                3(flag)176 LOAD_CONST              14(31)179 BINARY_SUBSCR       
            180 LOAD_CONST              15('}')183 COMPARE_OP               3(!=)186 POP_JUMP_IF_FALSE      20414>>189 LOAD_CONST               5('error')192 PRINT_ITEM          
            193 PRINT_NEWLINE       

 15194 LOAD_NAME                7(exit)197 CALL_FUNCTION            0200 POP_TOP             
            201 JUMP_FORWARD             0(to 204)17>>204 BUILD_LIST               0207 STORE_NAME               8(tmp)19210 SETUP_LOOP              37(to 250)213 LOAD_NAME                4(range)216 LOAD_NAME                1(a)219 CALL_FUNCTION            1222 GET_ITER            
        >>223 FOR_ITER                23(to 249)226 STORE_NAME               6(i)20229 LOAD_NAME                8(tmp)232 LOAD_ATTR                9(append)235 LOAD_NAME                3(flag)238 LOAD_NAME                6(i)241 BINARY_SUBSCR       
            242 CALL_FUNCTION            1245 POP_TOP             
            246 JUMP_ABSOLUTE          223>>249 POP_BLOCK           

 22>>250 SETUP_LOOP              44(to 297)253 LOAD_NAME                4(range)256 LOAD_NAME                1(a)259 CALL_FUNCTION            1262 GET_ITER            
        >>263 FOR_ITER                30(to 296)266 STORE_NAME               6(i)23269 LOAD_NAME               10(ord)272 LOAD_NAME                8(tmp)275 LOAD_NAME                6(i)278 BINARY_SUBSCR       
            279 CALL_FUNCTION            1282 LOAD_CONST              16(9)285 BINARY_SUBTRACT     
            286 LOAD_NAME                8(tmp)289 LOAD_NAME                6(i)292 STORE_SUBSCR        
            293 JUMP_ABSOLUTE          263>>296 POP_BLOCK           

 25>>297 SETUP_LOOP              38(to 338)300 LOAD_NAME                4(range)303 LOAD_NAME                1(a)306 CALL_FUNCTION            1309 GET_ITER            
        >>310 FOR_ITER                24(to 337)313 STORE_NAME               6(i)26316 LOAD_NAME                8(tmp)319 LOAD_NAME                6(i)322 BINARY_SUBSCR       
            323 LOAD_CONST              17(51)326 BINARY_XOR          
            327 LOAD_NAME                8(tmp)330 LOAD_NAME                6(i)333 STORE_SUBSCR        
            334 JUMP_ABSOLUTE          310>>337 POP_BLOCK           

 28>>338 SETUP_LOOP              38(to 379)341 LOAD_NAME                4(range)344 LOAD_NAME                1(a)347 CALL_FUNCTION            1350 GET_ITER            
        >>351 FOR_ITER                24(to 378)354 STORE_NAME               6(i)29357 LOAD_NAME                8(tmp)360 LOAD_NAME                6(i)363 BINARY_SUBSCR       
            364 LOAD_CONST              18(8)367 BINARY_ADD          
            368 LOAD_NAME                8(tmp)371 LOAD_NAME                6(i)374 STORE_SUBSCR        
            375 JUMP_ABSOLUTE          351>>378 POP_BLOCK           

 31>>379 LOAD_NAME                8(tmp)382 LOAD_NAME                1(a)385 LOAD_CONST              10(3)388 BINARY_SUBTRACT     
            389 BINARY_SUBSCR       
            390 STORE_NAME              11(tmp1)32393 LOAD_NAME                8(tmp)396 LOAD_NAME                1(a)399 LOAD_CONST               8(2)402 BINARY_SUBTRACT     
            403 BINARY_SUBSCR       
            404 STORE_NAME              12(tmp2)33407 LOAD_NAME                8(tmp)410 LOAD_NAME                1(a)413 LOAD_CONST               3(1)416 BINARY_SUBTRACT     
            417 BINARY_SUBSCR       
            418 STORE_NAME              13(tmp3)35421 SETUP_LOOP              58(to 482)424 LOAD_NAME                4(range)427 LOAD_NAME                1(a)430 LOAD_CONST              10(3)433 BINARY_SUBTRACT     
            434 CALL_FUNCTION            1437 GET_ITER            
        >>438 FOR_ITER                40(to 481)441 STORE_NAME               6(i)36444 LOAD_NAME                8(tmp)447 LOAD_NAME                1(a)450 LOAD_CONST               3(1)453 BINARY_SUBTRACT     
            454 LOAD_NAME                6(i)457 BINARY_SUBTRACT     
            458 LOAD_CONST              10(3)461 BINARY_SUBTRACT     
            462 BINARY_SUBSCR       
            463 LOAD_NAME                8(tmp)466 LOAD_NAME                1(a)469 LOAD_CONST               3(1)472 BINARY_SUBTRACT     
            473 LOAD_NAME                6(i)476 BINARY_SUBTRACT     
            477 STORE_SUBSCR        
            478 JUMP_ABSOLUTE          438>>481 POP_BLOCK           

 38>>482 LOAD_NAME               13(tmp3)485 LOAD_NAME                8(tmp)488 LOAD_CONST               2(0)491 STORE_SUBSCR        

 39492 LOAD_NAME               12(tmp2)495 LOAD_NAME                8(tmp)498 LOAD_CONST               3(1)501 STORE_SUBSCR        

 40502 LOAD_NAME               11(tmp1)505 LOAD_NAME                8(tmp)508 LOAD_CONST               8(2)511 STORE_SUBSCR        

 42512 SETUP_LOOP              58(to 573)515 LOAD_NAME                4(range)518 LOAD_NAME                1(a)521 CALL_FUNCTION            1524 GET_ITER            
        >>525 FOR_ITER                44(to 572)528 STORE_NAME               6(i)43531 LOAD_NAME                6(i)534 LOAD_CONST              19(7)537 BINARY_MODULO       
            538 LOAD_CONST               3(1)541 COMPARE_OP               2(==)544 POP_JUMP_IF_FALSE      55344547 JUMP_ABSOLUTE          525550 JUMP_FORWARD             0(to 553)45>>553 LOAD_NAME                8(tmp)556 LOAD_NAME                6(i)559 DUP_TOPX                 2562 BINARY_SUBSCR       
            563 LOAD_CONST              20(119)566 INPLACE_XOR         
            567 ROT_THREE           
            568 STORE_SUBSCR        
            569 JUMP_ABSOLUTE          525>>572 POP_BLOCK           

 48>>573 LOAD_NAME               14(open)576 LOAD_CONST              21('out')579 LOAD_CONST              22('w')582 CALL_FUNCTION            2585 SETUP_WITH              26(to 614)588 STORE_NAME              15(f)49591 LOAD_NAME               15(f)594 LOAD_ATTR               16(write)597 LOAD_NAME               17(str)600 LOAD_NAME                8(tmp)603 CALL_FUNCTION            1606 CALL_FUNCTION            1609 POP_TOP             
            610 POP_BLOCK           
            611 LOAD_CONST               1(None)>>614 WITH_CLEANUP        
            615 END_FINALLY         
            616 LOAD_CONST               1(None)619 RETURN_VALUE        

python字节码,直接手撕,结构为 源码行号 | 指令在函数中的偏移 | 指令符号 | 指令参数 | 实际参数值。
参考文章:python字节码
字节码

a =[56,17,99,1,47,4,2,62,75,102,8,242,16,242,97,97,100,107,16,9,10,3,117,20,80,87,242,2,6,119,7,17]
flag =''for i inrange(len(a)):if i%7==1:
        flag +=(chr(((a[i]-8)^51)+9))else:
        flag +=(chr((((a[i]^119)-8)^51)+9))print(flag)

十二、[GXYCTF 2019]luck_guy

unsigned __int64 get_flag(){unsignedint v0;// eaxint i;// [rsp+4h] [rbp-3Ch]int j;// [rsp+8h] [rbp-38h]
  __int64 s;// [rsp+10h] [rbp-30h] BYREFchar v5;// [rsp+18h] [rbp-28h]unsigned __int64 v6;// [rsp+38h] [rbp-8h]

  v6 =__readfsqword(0x28u);
  v0 =time(0LL);srand(v0);for( i =0; i <=4;++i ){switch(rand()%200){case1:puts("OK, it's flag:");memset(&s,0,0x28uLL);strcat((char*)&s, f1);strcat((char*)&s,&f2);printf("%s",(constchar*)&s);break;case2:printf("Solar not like you");break;case3:printf("Solar want a girlfriend");break;case4:
        s =0x7F666F6067756369LL;
        v5 =0;strcat(&f2,(constchar*)&s);break;case5:for( j =0; j <=7;++j ){if( j %2==1)*(&f2 + j)-=2;else--*(&f2 + j);}break;default:puts("emmm,you can't find flag 23333");break;}}return__readfsqword(0x28u)^ v6;}

在这里插入图片描述

flag拼接了f1和f2,f1直接给出,f2与s拼接,并做了case5的处理,注意0x7F666F6067756369LL是小端,逆序的,所以解密的时候要反过来

s =[0x7F,0x66,0x6F,0x60,0x67,0x75,0x63,0x69][::-1]
flag ='GXY{do_not_'for i inrange(8):if i %2==1:
        s[i]-=2else:
        s[i]-=1
    flag +=chr(s[i])print(flag)

十三、[HNCTF 2022 Week1]Little Endian

int __cdecl main(int argc,constchar**argv,constchar**envp){char v4[36];// [rsp+20h] [rbp-30h] BYREFint i;// [rsp+44h] [rbp-Ch]char*v6;// [rsp+48h] [rbp-8h]_main();puts("please input your flag");scanf("%s", v4);
  v6 = v4;for( i =0; i <=5;++i ){if(*(_DWORD *)v6 !=(enc[i]^0x12345678)){printf("Data3rr0r!");exit(0);}
    v6 +=4;}printf("you are right!");return0;}

直接从题目可以知道小端存储,即最低位的字节数据存在最低地址上,而次低位的字节数据按次序排列在次低的地址上,所以反着来就好。

enc =[1365706038,1582239788,2118132241,2087782731,2085961500,1868183574]
flag =''
l =[]for i inrange(len(enc)):
    flag = enc[i]^0x12345678
    l.append(hex(flag).replace('0x',''))print(l)for k in l:
    i=len(k)-2while i >=0:
        num = k[i:i +2]print(chr(int(num,16)), end="")
        i = i -2

十四、[MoeCTF 2021]Realezpy

# uncompyle6 version 3.8.0# Python bytecode 3.8.0 (3413)# Decompiled from: Python 3.9.8 (tags/v3.9.8:bb3fdcf, Nov  5 2021, 20:48:33) [MSC v.1929 64 bit (AMD64)]# Embedded file name: Ezpython.py# Compiled at: 2021-07-28 10:01:40# Size of source mod 2**32: 931 bytesimport time
c =[119,121,111,109,100,112,123,74,105,100,114,48,120,95,49,99,95,99,121,48,121,48,121,48,121,48,95,111,107,99,105,125]defdecrypt(a):
    result=[]for i inrange(len(a)):iford('a')<= a[i]<=ord('z'):
            result.append((a[i]-114-ord('a'))%26+ord('a'))eliford('A')<= a[i]<=ord('Z'):
            result.append((a[i]-514-ord('A'))%26+ord('A'))else:
            result.append(a[i])else:return result
result=decrypt(c)
flag=''for i in result:
    flag+=chr(i)print(flag)

十五、[HGAME 2023 week1]encode

int __cdecl main(int argc,constchar**argv,constchar**envp){int v4[100];// [esp+0h] [ebp-1CCh] BYREFchar v5[52];// [esp+190h] [ebp-3Ch] BYREFint j;// [esp+1C4h] [ebp-8h]int i;// [esp+1C8h] [ebp-4h]memset(v5,0,0x32u);memset(v4,0,sizeof(v4));sub_4011A0(a50s,(char)v5);for( i =0; i <50;++i ){
    v4[2* i]= v5[i]&0xF;
    v4[2* i +1]=(v5[i]>>4)&0xF;}for( j =0; j <100;++j ){if( v4[j]!= dword_403000[j]){sub_401160(Format, v4[0]);return0;}}sub_401160(aYesYouAreRight, v4[0]);return0;}

就是将输入的字符串一个字节切割成两部分,即每部分4个字节,然后对比,完全正确则正确。

在这里插入图片描述

c =[8,6,7,6,1,6,13,6,5,6,11,7,5,6,14,6,3,6,15,6,4,6,5,6,15,5,9,6,3,7,15,5,5,6,1,6,3,7,9,7,15,5,6,6,15,6,2,7,15,5,1,6,15,5,2,7,5,6,6,7,5,6,2,7,3,7,5,6,15,5,5,6,14,6,7,6,9,6,14,6,5,6,5,6,2,7,13,7,0,0,0,0,0,0,0,0,0,0,0,0]
flag =''for i inrange(50):
    t =(c[i *2+1]<<4)+ c[i *2]
    flag +=chr(t)print(flag)
标签: web安全

本文转载自: https://blog.csdn.net/weixin_53090346/article/details/129099449
版权归原作者 Aiwin-Hacker 所有, 如有侵权,请联系我们删除。

“Reverse入门[不断记录]”的评论:

还没有评论