第一题easyre
ida查壳直接看
flag{this_Is_a_EaSyRe}
第二题reverse1
定位到Str2{hello_world}
根据
for ( j = 0; ; ++j )
{
v8 = j;
v2 = j_strlen(Str2);
if ( v8 > v2 )
break;
if ( Str2[j] == 'o' )
Str2[j] = '0';
}
把o换成0
flag{hell0_w0rld}
第三题reverse2
ELF即linux 下可执行文件
先用ida看看
找到{hacking_for_fun}
定位到关键代码
for ( i = 0; i <= strlen(&flag); ++i )
{
if ( *(&flag + i) == 'i' || *(&flag + i) == 'r' )
*(&flag + i) = '1';
}
把i或者r换成1
直接换flag{hack1ng_fo1_fun}
第四题内涵的软件
直接看
v6 = 5;
v5 = "DBAPP{49d3c93df25caad81232130f3d2ebfad}";
while ( v6 >= 0 )
{
printf("距离出现答案还有%d秒,请耐心等待!\n", v6);
sub_40100A();
--v6;
}
printf(
"\n"
"\n"
"\n"
"这里本来应该是答案的,但是粗心的程序员忘记把变量写进来了,你要不逆向试试看:(Y/N)\n");
v4[0] = 1;
scanf("%c", v4);
if ( v4[0] == 'Y' )
{
printf("OD吾爱破解或者IDA这些逆向软件都挺好的!");
result = sub_40100A();
}
else
{
if ( v4[0] == 'N' )
printf("那没办法了,猜是猜不出的.");
else
printf(&byte_42501C);
result = sub_40100A();
}
return result;
v5十分可疑,直接flag{49d3c93df25caad81232130f3d2ebfad}
第五题新年快乐
查壳,发现UPX,直接脱壳
定位关键
__main();
strcpy(Str2, "HappyNewYear!");
Str1 = 0;
memset(v6, 0, sizeof(v6));
printf("please input the true flag:");
scanf("%s", &Str1);
if ( !strncmp((const char *)&Str1, Str2, strlen(Str2)) )
result = puts("this is true flag!");
else
result = puts("wrong!");
return result;
Str2就是flag
flag{HappyNewYear!}
第六题xor
mac 64位
ida进
定位关键的代码
memset(__b, 0, 0x100uLL);
printf("Input your flag:\n");
get_line(__b, 256LL);
if ( strlen(__b) != 33 )
goto LABEL_7;
for ( i = 1; i < 33; ++i )
__b[i] ^= __b[i - 1];
if ( !strncmp(__b, global, 0x21uLL) )
printf("Success");
else
LABEL_7:
printf("Failed");
return 0;
分析flag 33位,进入异或后和global相等
导出global
unsigned char aFK[] =
{
102, 10, 107, 12, 119, 38, 79, 46, 64, 17,
120, 13, 90, 59, 85, 17, 112, 25, 70, 31,
118, 34, 77, 35, 68, 14, 103, 6, 104, 15,
71, 50, 79
};
写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char str[]={
102, 10, 107, 12, 119, 38, 79, 46, 64, 17,
120, 13, 90, 59, 85, 17, 112, 25, 70, 31,
118, 34, 77, 35, 68, 14, 103, 6, 104, 15,
71, 50, 79
};
int i,len = 33;
for(i=len-1;i>=1;i--){str[i]^=str[i-1];}
puts(str);
}
//flag{QianQiuWanDai_YiTongJiangHu}
第七题helloword
apk逆向,准备工具jadx
定位到关键代码
package com.example.helloword;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
/* access modifiers changed from: protected */
@Override // android.support.v7.app.ActionBarActivity, android.support.v4.app.FragmentActivity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
"flag{7631a988259a00816deda84afb29430a}".compareTo("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
直接提取flag
flag{7631a988259a00816deda84afb29430a}
第八题reverse3
ida打开
定位到关键代码
sub_41132F("please enter the flag:", v7);
sub_411375("%20s", (char)Str);
v3 = j_strlen(Str);
v4 = (const char *)sub_4110BE(Str, v3, v14);
strncpy(Destination, v4, 0x28u);
v11 = j_strlen(Destination);
for ( j = 0; j < v11; ++j )
Destination[j] += j;
v5 = j_strlen(Destination);
if ( !strncmp(Destination, Str2, v5) )
sub_41132F("rigth flag!\n", v8);
else
sub_41132F("wrong flag!\n", v8);
return 0;
接着分享 flag给到了Str,进入了函数sub_4110BE(Str, v3, v14);处理
然后处理为v4,v4复制到Destination,Destination进行加操作,接着和Str2比较
我们发现sub_4110BE对字符串flag进行base64加密(字符特征)
Str2=“e3nifIH9b_C@n@dH”
直接写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char str[]="e3nifIH9b_C@n@dH";
int i,len = strlen(str);
for(i=0;i<len;i++){str[i]-=i;}
puts(str);
}
//e2lfbDB2ZV95b3V9
//拿着e2lfbDB2ZV95b3V9进行常规base64解密
//flag{i_l0ve_you}
第九题不一样的flag
有点像游戏,用ida打开
f5直接看,定位到
strcpy(v3, "*11110100001010000101111#");
for ( i = 0; i <= 1; ++i )
{
if ( *(&v4 + i) < 0 || *(&v4 + i) > 4 )
exit(1);
}
if ( v8[5 * v4 - 41 + v5] == '1' )
exit(1);
if ( v8[5 * v4 - 41 + v5] == '#' )
{
puts("\nok, the order you enter is the flag!");
exit(0);
}
首先
puts("1 up");
puts("2 down");
puts("3 left");
printf("4 right\n:");
超出1到范围直接退出
其次在数组v3种遇到1或者#直接退出,但#提示我们输入的就是flag,这是一道典型的迷宫题
根据二维数组公式结合
if ( v8[5 * v4 - 41 + v5] == '1' )
exit(1);
if ( v8[5 * v4 - 41 + v5] == '#' )
假设迷宫一列5位,v4是行,v5是列
*1111
01000
01010
00010
1111#
我们这种迷宫直接手写,如果是复杂的那种要用递归写。
flag{222441144222}
第十题SimpleRev
ELF文件
定位到Decry()关键函数
unsigned __int64 Decry()
{
char v1; // [rsp+Fh] [rbp-51h]
int v2; // [rsp+10h] [rbp-50h]
int v3; // [rsp+14h] [rbp-4Ch]
int i; // [rsp+18h] [rbp-48h]
int v5; // [rsp+1Ch] [rbp-44h]
char src[8]; // [rsp+20h] [rbp-40h] BYREF
__int64 v7; // [rsp+28h] [rbp-38h]
int v8; // [rsp+30h] [rbp-30h]
__int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
int v10; // [rsp+50h] [rbp-10h]
unsigned __int64 v11; // [rsp+58h] [rbp-8h]
v11 = __readfsqword(0x28u);
*(_QWORD *)src = 'SLCDN';
v7 = 0LL;
v8 = 0;
v9[0] = 'wodah';
v9[1] = '\0';
v10 = 0;
text = (char *)join(key3, v9); // key3="killshadow"
strcpy(key, key1);
strcat(key, src); // key="ADSFKNDCLS"
v2 = 0;
v3 = 0;
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
key[i] = key[v3 % v5] + 32;
++v3;
}
printf("Please input your flag:");
while ( 1 )
{
v1 = getchar();
if ( v1 == 10 )
break;
if ( v1 == 32 )
{
++v2;
}
else
{
if ( v1 <= '`' || v1 > 'z' )
{
if ( v1 > '@' && v1 <= 'Z' )
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
}
else
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) )
puts("Congratulation!\n");
else
puts("Try again!\n");
return __readfsqword(0x28u) ^ v11;
}
text=str2 为key3,key经过变化后,与flag操作成为Str2
注意,大小端的问题,我们换成字符串的时候要注意顺序
我们直接写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char key[]="adsfkndcls";
char str2[]="killshadow";
int v5 = strlen(key);
char flag[v5+1];
flag[v5] = '\0';
int i;
int j = 0;
for( i = 0; i < v5; ++i ){
j = 0;
for( j = 0;j<10;j++) {
flag[i]=str2[i]-97+26*j+39-97+key[i];
if( flag[i]<='Z'&&flag[i]>='A'||flag[i]>='a'&&flag[i]<='z')
break;
}
}
puts(flag);
}
第十一题JAVA逆向
用jadx打开
package defpackage;
import java.util.ArrayList;
import java.util.Scanner;
/* renamed from: Reverse reason: default package */
public class Reverse {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Please input the flag :");
String str = s.next();
System.out.println("Your input is :");
System.out.println(str);
Encrypt(str.toCharArray());
}
public static void Encrypt(char[] arr) {
int[] KEY;
ArrayList<Integer> Resultlist = new ArrayList<>();
for (char c : arr) {
Resultlist.add(Integer.valueOf((c) +'@' ^ 32));
}
ArrayList<Integer> KEYList = new ArrayList<>();
for (int i : new int[]{180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65}) {
KEYList.add(Integer.valueOf(i));
}
System.out.println("Result:");
if (Resultlist.equals(KEYList)) {
System.out.println("Congratulations!");
} else {
System.err.println("Error!");
}
}
}
显而易见,直接写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char enflag[]={180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
int len = strlen(enflag);
char flag[len + 1];
flag[len] = '\0';
int i;
for(i = 0; i < len; i++){
flag[i] = enflag[i]-'@'^32;
}
puts(flag);
}
//flag{This_is_the_flag_!}
第十二题[GXYCTF2019]luck_guy
定位关键代码
v5 = __readfsqword(0x28u);
v0 = time(0LL);
srand(v0);
for ( i = 0; i <= 4; ++i )
{
switch ( rand() % 200 )
{
case 1:
puts("OK, it's flag:");
memset(s, 0, sizeof(s));
strcat((char *)s, f1); // GXY{do_not_
strcat((char *)s, &f2);
printf("%s", (const char *)s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
strcpy((char *)s, "icug`of\x7F");
strcat(&f2, (const char *)s);
break;
case 5:
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;
}
逻辑简单,我们直接拿到上半部分GXY{do_not_
下半部分直接写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char s[]="icug`of\x7F";
int j;
int len = strlen(s);
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
s[j]-= 2;
else
s[j] -=1;
}
puts( s );
}
//hate_me}
flag{do_not_hate_me}
第十三题刮开有奖
定位到关键代码
INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[10]; // [esp+8h] [ebp-20030h] BYREF
int v8; // [esp+30h] [ebp-20008h]
CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
char v10[65536]; // [esp+10034h] [ebp-10004h] BYREF
if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 == 1001 )
{
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 )
{
v7[0] = 90;
v7[1] = 74;
v7[2] = 83;
v7[3] = 69;
v7[4] = 67;
v7[5] = 97;
v7[6] = 78;
v7[7] = 72;
v7[8] = 51;
v7[9] = 110;
v8 = 103;
sub_4010F0(v7, 0, 10);
memset(v10, 0, 0xFFFFu);
v10[0] = String[5];
v10[2] = String[7];
v10[1] = String[6];
v4 = (const char *)sub_401000(v10, strlen(v10));
memset(v10, 0, 0xFFFFu);
v10[1] = String[3];
v10[0] = String[2];
v10[2] = String[4];
v5 = (const char *)sub_401000(v10, strlen(v10));
if ( String[0] == v7[0] + 34
&& String[1] == v7[4]
&& 4 * String[2] - 141 == 3 * v7[2]
&& String[3] / 4 == 2 * (v7[7] / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
return 0;
EndDialog(hDlg, (unsigned __int16)a3);
return 1;
}
这道题让我学会了,如果动态调试调不了,可以把代码copy下来,自己跑。
先说说思路String的后6位很简单,解base64就出来了,但前2位是要进过sub_4010F0函数变化得到的,重点就到了加密上。太多太复杂,我动态调试,结果跑不到我的断点。看到大佬的WP让我感悟到可以直接copy代码,自己跑
我们得知道加密后的v7
#include<stdio.h>
void sub_7310F0(int *v7, int a2, int a3)
{
int v3; // eax
int i; // esi
int v5; // ecx
int v6; // edx
v3 = a3;
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = v7[i];
if ( a2 < v3 && i < v3 )
{
do
{
if ( v6 > v7[v3] )
{
if ( i >= v3 )
break;
++i;
v7[v5] = v7[v3];
if ( i >= v3 )
break;
while ( v7[i] <= v6 )
{
if ( ++i >= v3 )
goto LABEL_13;
}
if ( i >= v3 )
break;
v5 = i;
v7[v3] = v7[i];
}
--v3;
}
while ( i < v3 );
}
LABEL_13:
v7[v3] = v6;
sub_7310F0(v7, a2, i - 1);
v3 = a3;
++i;
}
}
int main()
{
int v7[11];
v7[0] = 90;
v7[1] = 74;
v7[2] = 83;
v7[3] = 69;
v7[4] = 67;
v7[5] = 97;
v7[6] = 78;
v7[7] = 72;
v7[8] = 51;
v7[9] = 110;
v7[10] = 103;
sub_7310F0(v7,0,10);
for ( int i = 0; i <10;i++)
{
printf("%c",v7[i]);
}
//3CEHJNSZag
}
然后直接解
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char v7[11]="3CEHJNSZag";
char String[9];
String[0] = v7[0] + 34;
String[1] = v7[4];
String[5]='j';
String[6]='M';
String[7]='p';
String[2]= 'W';
String[3]='P';
String[4]='1';
String[8]='\0';
puts(String);
//UJWP1jMp
}
第十四题[BJDCTF2020]JustRE
定位到关键代码
sprintf(String, " BJD{%d%d2069a45792d233ac}", 19999, 0);
flag{1999902069a45792d233ac}
第十六题简单注册器
apk逆向
定位到关键代码
public void onClick(View v) {
int flag = 1;
String xx = editview.getText().toString();
if (!(xx.length() == 32 && xx.charAt(31) == 'a' && xx.charAt(1) == 'b' && (xx.charAt(0) + xx.charAt(2)) - 48 == 56)) {
flag = 0;
}
if (flag == 1) {
char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
x[2] = (char) ((x[2] + x[3]) - 50);
x[4] = (char) ((x[2] + x[5]) - 48);
x[30] = (char) ((x[31] + x[9]) - 48);
x[14] = (char) ((x[27] + x[28]) - 97);
for (int i = 0; i < 16; i++) {
char a = x[31 - i];
x[31 - i] = x[i];
x[i] = a;
}
textview.setText("flag{" + String.valueOf(x) + "}");
return;
}
textview.setText("输入注册码错误");
}
});
}
写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char x[]= "dd2940c04462b4dd7c450528835cca15";
x[2] = (char) ((x[2] + x[3]) - 50);
x[4] = (char) ((x[2] + x[5]) - 48);
x[30] = (char) ((x[31] + x[9]) - 48);
x[14] = (char) ((x[27] + x[28]) - 97);
for (int i = 0; i < 16; i++) {
char a = x[31 - i];
x[31 - i] = x[i];
x[i] = a;
}
puts(x);
//59acc538825054c7de4b26440c0999dd
}
第十七题GWCTF 2019]pyre
pyc逆向
直接逆向
# uncompyle6 version 3.8.0
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)]
# Embedded file name: encode.py
# Compiled at: 2019-08-19 21:01:57
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128
code += num
for i in range(l - 1):
code[i] = code[i] ^ code[(i + 1)]
print code
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
# okay decompiling 1.pyc
直接写EXP
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char code[]={'\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13'};
int i, len =strlen(code);
for(i=len-2; i>=0; i--){
code[i] = code[i] ^ code[(i + 1)];
}
char flag[len+1];
flag[len] = '\0';
for(i=0; i<=len-1; i++){
int j = 0;
for(j = 0;j<2;j++)
{
flag[i] = code[i] -i+j*128;
if(flag[i]<=126&&flag[i]>=0) break;
}
}
puts(flag);
}
//GWHT{Just_Re_1s_Ha66y!}
flag{Just_Re_1s_Ha66y!}
第十八题[ACTF新生赛2020]easyre
UPX直接脱壳
关键部分
__main();
qmemcpy(v4, "*F'"N,"(I?+@", sizeof(v4));
printf("Please input:");
scanf("%s", v6);
if ( v6[0] != 'A' || v6[1] != 'C' || v6[2] != 'T' || v6[3] != 'F' || v6[4] != '{' || v10 != '}' )//ACTF{*F'"N,"(I?+@}
return 0;
v5[0] = v7;
v5[1] = v8;
v5[2] = v9;
for ( i = 0; i <= 11; ++i )
{
if ( v4[i] != _data_start__[*((char *)v5 + i) - 1] )
return 0;
}
printf("You are correct!");
return 0;
}
if ( v4[i] != enflag[*((char *)v5 + i) - 1] )
v4[i]=enflag[j];
v5[i]=j+1;
这次上python脚本
code='''~}|{zyxwvutsrqponmlkjihgfedcba`_^][ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$# !"'''
v4='''*F'"N,"(I?+@''';
flag=""
for i in range(len(v4)):
for j in range(len(code)):
if ord(v4[i]) == ord(code[j]):
flag+=chr(j+1)
print(flag)
#U9X_1S_W6@T?
第十九题RSA
提取公钥指数及模数信息:
| 模数: | C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD |
|---|---|
| 指数: | 65537 (0x10001) |
表示n=0xC0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD
e=65537
则
n=86934482296048119190666062003494800588905656017203025617216654058378322103517
q=285960468890451637935629440372639283459
p=304008741604601924494328155975272418463
然后就是rsa的使用了,
别人的wp
import gmpy2
import rsa
e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
phin = (q-1)*(p-1)
d = gmpy2.invert(e, phin)
key = rsa.PrivateKey(n, e, int(d), p, q)
with open("flag.enc", "rb+") as f:
f = f.read()
print(rsa.decrypt(f, key))
第二十题rome
定位关键代码
int func()
{
int result; // eax
int v1[4]; // [esp+14h] [ebp-44h]
unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
unsigned __int8 v3; // [esp+25h] [ebp-33h]
unsigned __int8 v4; // [esp+26h] [ebp-32h]
unsigned __int8 v5; // [esp+27h] [ebp-31h]
unsigned __int8 v6; // [esp+28h] [ebp-30h]
int v7; // [esp+29h] [ebp-2Fh]
int v8; // [esp+2Dh] [ebp-2Bh]
int v9; // [esp+31h] [ebp-27h]
int v10; // [esp+35h] [ebp-23h]
unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF
strcpy(v12, "Qsw3sj_lz4_Ujw@l");
printf("Please input:");
scanf("%s", &v2);
result = v2;
if ( v2 == 'A' )
{
result = v3;
if ( v3 == 'C' )
{
result = v4;
if ( v4 == 'T' )
{
result = v5;
if ( v5 == 'F' )
{
result = v6;
if ( v6 == '{' )
{
result = v11;
if ( v11 == '}' )
{
v1[0] = v7;
v1[1] = v8;
v1[2] = v9;
v1[3] = v10;
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > '@' && *((char *)v1 + *(_DWORD *)&v12[17]) <= 'Z' )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > '`' && *((char *)v1 + *(_DWORD *)&v12[17]) <= 'z' )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
++*(_DWORD *)&v12[17];
}
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
return result;
++*(_DWORD *)&v12[17];
}
result = printf("You are correct!");
}
}
}
}
}
}
return result;
}
不好看,把关键部分化简一下
j = 0;
while ( j <= 15 )
{
if ( v1[j] > '@' && v1[j] <= 'Z' )
v1[j] = (v1[j] - 51) % 26 + 65;
if ( v1[j] > '`' && v1[j] <= 'z' )
v1[j] = (v1[j] - 79) % 26 + 97;
++j;
}
j = 0;
while ( j <= 15 )
{
char result = (unsigned __int8)v12[j];
if ( v1[j] != result )
return result;
++j;
}
result = printf("You are correct!");
然后while化成for,主要我不习惯
for(j = 0;j<=15;j++)
{
if ( v1[j] > '@' && v1[j] <= 'Z' )
v1[j] = (v1[j] - 51) % 26 + 65;
if ( v1[j] > '`' && v1[j] <= 'z' )
v1[j] = (v1[j] - 79) % 26 + 97;
}
for(j = 0;j<=15;j++)
{
char result = (unsigned __int8)v12[j];
if ( v1[j] != result )
return result;
}
//v12="Qsw3sj_lz4_Ujw@l"
好了逻辑到这里就很清楚了
EXP
v1="Qsw3sj_lz4_Ujw@l"
flag=""
j = 0
for i in v1:
if i > '`' and i <= 'z' :
for k in range(10):
z=chr(ord(i)-97+k*26+79)
if z<='z'and z>'`':
flag+=z
print(flag)
break;
elif i > '@' and i <= 'Z':
for k in range(10):
z=chr(ord(i)-65+k*26+51)
if z<='Z'and z>'@':
flag+=z
print(flag)
break;
else: flag+=i
print(flag)
\