[HDCTF2019]Maze
脱壳, IDA打开, 发现无法F5, 而且反汇编失败
这种情况一般是花指令, 误导了IDA的递归反汇编, 这里E8
是call指令, nop掉按p
设置main函数入口再F5
即可
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+0h] [ebp-24h]
int v5; // [esp+0h] [ebp-24h]
int i; // [esp+10h] [ebp-14h]
char v7[16]; // [esp+14h] [ebp-10h] BYREF
sub_401140((int)aGoThroughTheMa, v4);
scanf("%14s", v7);
for ( i = 0; i <= 13; ++i )
{
switch ( v7[i] )
{
case 'a':
--*(_DWORD *)asc_408078;
break;
case 'd':
++*(_DWORD *)asc_408078;
break;
case 's':
--dword_40807C;
break;
case 'w':
++dword_40807C;
break;
default:
continue;
}
}
if ( *(_DWORD *)asc_408078 == 5 && dword_40807C == -4 )
{
sub_401140((int)aCongratulation, v5);
sub_401140((int)aHereIsTheFlagF, (int)v7);
}
else
{
sub_401140((int)aTryAgain, v5);
}
return 0;
}
顾名思义, 走迷宫, dump出迷宫
mazestr = '*******+********* ****** **** ******* **F****** **************'
length = len(mazestr)
for row in range(5, 10):
maze = []
col = length // row
for j in range(row):
maze.append(mazestr[j*col: j*col+col])
for each in maze:
print(each)
print()
'''
*******+**
******* **
**** **
** *****
** **F****
** ****
**********
'''
14步内走出迷宫即可
相册
Android逆向, jadx打开, 定位到主逻辑
package cn.baidujiayuan.ver5304;
import java.util.Date;
import java.util.Properties;
import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class Mail extends Authenticator {
private boolean _auth;
private String _body;
private boolean _debuggable;
private String _from;
private String _host;
private Multipart _multipart;
private String _pass;
private String _port;
private String _sport;
private String _subject;
private String[] _to;
private String _user;
public Mail() {
this._host = "smtp.qq.com";
this._port = "465";
this._sport = "465";
this._user = "";
this._from = "";
this._subject = "";
this._body = "";
this._debuggable = false;
this._auth = true;
this._multipart = new MimeMultipart();
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mc);
}
public String get_user() {
return this._user;
}
public void set_user(String _user2) {
this._user = _user2;
}
public String get_pass() {
return this._pass;
}
public void set_pass(String _pass2) {
this._pass = _pass2;
}
public String[] get_to() {
return this._to;
}
public void set_to(String[] _to2) {
this._to = _to2;
}
public String get_from() {
return this._from;
}
public void set_from(String _from2) {
this._from = _from2;
}
public String get_port() {
return this._port;
}
public void set_port(String _port2) {
this._port = _port2;
}
public String get_sport() {
return this._sport;
}
public void set_sport(String _sport2) {
this._sport = _sport2;
}
public String get_host() {
return this._host;
}
public void set_host(String _host2) {
this._host = _host2;
}
public String get_subject() {
return this._subject;
}
public void set_subject(String _subject2) {
this._subject = _subject2;
}
public String get_body() {
return this._body;
}
public void set_body(String _body2) {
this._body = _body2;
}
public boolean is_auth() {
return this._auth;
}
public void set_auth(boolean _auth2) {
this._auth = _auth2;
}
public boolean is_debuggable() {
return this._debuggable;
}
public void set_debuggable(boolean _debuggable2) {
this._debuggable = _debuggable2;
}
public Multipart get_multipart() {
return this._multipart;
}
public void set_multipart(Multipart _multipart2) {
this._multipart = _multipart2;
}
public Mail(String user, String pass) {
this();
this._user = user;
this._pass = pass;
}
public boolean send() throws Exception {
Properties props = _setProperties();
if (this._user.equals("") || this._pass.equals("") || this._to.length <= 0 || this._from.equals("") || this._subject.equals("") || this._body.equals("")) {
return false;
}
MimeMessage msg = new MimeMessage(Session.getInstance(props, this));
msg.setFrom(new InternetAddress(this._from));
InternetAddress[] addressTo = new InternetAddress[this._to.length];
for (int i = 0; i < this._to.length; i++) {
addressTo[i] = new InternetAddress(this._to[i]);
}
msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);
msg.setSubject(this._subject);
msg.setSentDate(new Date());
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(this._body);
this._multipart.addBodyPart(messageBodyPart);
msg.setContent(this._multipart);
Transport.send(msg);
return true;
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(new FileDataSource(filename)));
messageBodyPart.setFileName(filename);
this._multipart.addBodyPart(messageBodyPart);
}
@Override // javax.mail.Authenticator
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(this._user, this._pass);
}
private Properties _setProperties() {
Properties props = new Properties();
props.put("mail.smtp.host", this._host);
if (this._debuggable) {
props.put("mail.debug", "true");
}
if (this._auth) {
props.put("mail.smtp.auth", "true");
}
props.put("mail.smtp.port", this._port);
props.put("mail.smtp.socketFactory.port", this._sport);
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
return props;
}
public String getBody() {
return this._body;
}
public void setBody(String _body2) {
this._body = _body2;
}
}
查找用例, 找到调用者
public static int sendMailByJavaMail(String mailto, String title, String mailmsg) {
if (!debug) {
Mail m = new Mail(C2.MAILUSER, C2.MAILPASS);
m.set_host(C2.MAILHOST);
m.set_port(C2.PORT);
m.set_debuggable(true);
m.set_to(new String[]{mailto});
m.set_from(C2.MAILFROME);
m.set_subject(title);
m.setBody(mailmsg);
try {
if (m.send()) {
Log.i("IcetestActivity", "Email was sent successfully.");
} else {
Log.i("IcetestActivity", "Email was sent failed.");
}
} catch (Exception e) {
Log.e("MailApp", "Could not send email", e);
}
}
return 1;
}
找到MAILFROME
的赋值
package cn.baidujiayuan.ver5304;
import android.content.Context;
import com.net.cn.NativeMethod;
import it.sauronsoftware.base64.Base64;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
public class C2 {
public static final String CANCELNUMBER = "%23%2321%23";
public static final String MAILFROME = Base64.decode(NativeMethod.m());
public static final String MAILHOST = "smtp.163.com";
public static final String MAILPASS = Base64.decode(NativeMethod.pwd());
public static final String MAILSERVER = Base64.decode(NativeMethod.m());
public static final String MAILUSER = Base64.decode(NativeMethod.m());
public static final String MOVENUMBER = "**21*121%23";
public static final String PORT = "25";
public static final String date = "2115-11-1";
public static final String phoneNumber = Base64.decode(NativeMethod.p());
static {
System.loadLibrary("core");
}
public static Date strToDateLong(String strDate) {
return new SimpleDateFormat("yyyy-MM-dd").parse(strDate, new ParsePosition(0));
}
public static boolean isFilter(Context context) {
if (strToDateLong(date).getTime() - new Date().getTime() < 0) {
return true;
}
return false;
}
public static boolean isServerFilter(Context context) {
if (context.getSharedPreferences("X", 0).getString("m", A2.FILTERSETUPTAG).equals(A2.FILTERSETUPTAG)) {
return true;
}
return false;
}
}
往下就是native层逆向, 找到base64的输入, 即m方法的输出
IDA打开libcore.so
解码, 完事
[MRCTF2020]Xor
无壳, 但是不能直接F5, 但是逻辑简单, 直接读汇编
关键逻辑
mov cl, byte_4212C0[eax]
xor cl, al
cmp cl, ds:byte_41EA08[eax]
jnz short loc_4010FF
REV
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "MSAWB~FXZ:J:`tQJ\"N@ bpdd}8g";
string flag = "";
for (int i = 0; i < s.size(); ++i)
flag += i ^ s[i];
cout << flag << endl;
}
[MRCTF2020]hello_world_go
go逆向, IDA分析
// main.main
void __cdecl main_main()
{
__int64 v0; // rcx
__int64 v1; // rax
__int64 v2; // rax
__int64 v3; // [rsp+20h] [rbp-90h]
__int64 v4; // [rsp+58h] [rbp-58h]
__int64 *v5; // [rsp+60h] [rbp-50h]
__int64 v6[2]; // [rsp+68h] [rbp-48h] BYREF
__int64 v7[2]; // [rsp+78h] [rbp-38h] BYREF
__int64 v8[2]; // [rsp+88h] [rbp-28h] BYREF
__int64 v9[2]; // [rsp+98h] [rbp-18h] BYREF
v5 = (__int64 *)runtime_newobject((__int64)&RTYPE_string);
v9[0] = (__int64)&RTYPE_string;
v9[1] = (__int64)&off_4EA530;
fmt_Fprint((__int64)&go_itab__ptr_os_File_comma_io_Writer, os_Stdout, (__int64)v9, 1LL, 1LL);
v8[0] = (__int64)&RTYPE__ptr_string;
v8[1] = (__int64)v5;
fmt_Fscanf((__int64)&go_itab__ptr_os_File_comma_io_Reader, os_Stdin, (__int64)"%s", 2LL, (__int64)v8, 1LL, 1LL);
v0 = v5[1];
v1 = *v5;
if ( v0 != 24 )
goto LABEL_2;
v4 = *v5;
if ( !runtime_memequal((__int64)"flag{hello_world_gogogo}", v1, 24LL) )
{
v1 = v4;
v0 = 24LL;
LABEL_2:
runtime_cmpstring((__int64)"flag{hello_world_gogogo}", 24LL, v1, v0, v3);
if ( v3 >= 0 )
v2 = 1LL;
else
v2 = -1LL;
goto LABEL_4;
}
v2 = 0LL;
LABEL_4:
if ( v2 )
{
v6[0] = (__int64)&RTYPE_string;
v6[1] = (__int64)&off_4EA550;
fmt_Fprintln((__int64)&go_itab__ptr_os_File_comma_io_Writer, os_Stdout, (__int64)v6, 1LL, 1LL);
}
else
{
v7[0] = (__int64)&RTYPE_string;
v7[1] = (__int64)&off_4EA540;
fmt_Fprintln((__int64)&go_itab__ptr_os_File_comma_io_Writer, os_Stdout, (__int64)v7, 1LL, 1LL);
}
}
白给
[WUSTCTF2020]level3
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rax
char v5; // [rsp+Fh] [rbp-41h]
char v6[56]; // [rsp+10h] [rbp-40h] BYREF
unsigned __int64 v7; // [rsp+48h] [rbp-8h]
v7 = __readfsqword(0x28u);
printf("Try my base64 program?.....\n>");
__isoc99_scanf("%20s", v6);
v5 = time(0LL);
srand(v5);
if ( (rand() & 1) != 0 )
{
v3 = (const char *)base64_encode(v6);
puts(v3);
puts("Is there something wrong?");
}
else
{
puts("Sorry I think it's not prepared yet....");
puts("And I get a strange string from my program which is different from the standard base64:");
puts("d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD==");
puts("What's wrong??");
}
return 0;
}
char *__fastcall base64_encode(char *a1)
{
int v1; // eax
int v2; // eax
int v4; // [rsp+1Ch] [rbp-54h]
int v5; // [rsp+20h] [rbp-50h]
int v6; // [rsp+24h] [rbp-4Ch]
int v7; // [rsp+28h] [rbp-48h]
int v8; // [rsp+2Ch] [rbp-44h]
char src[56]; // [rsp+30h] [rbp-40h] BYREF
unsigned __int64 v10; // [rsp+68h] [rbp-8h]
v10 = __readfsqword(0x28u);
v1 = strlen(a1);
v8 = v1 % 3;
v7 = v1 / 3;
memset(src, 0, 0x30uLL);
v6 = 0;
v4 = 0;
v5 = 0;
while ( v4 < v7 )
{
src[v6] = base64_table[a1[v5] >> 2];
src[v6 + 1] = base64_table[(16 * (a1[v5] & 3)) | (a1[v5 + 1] >> 4)];
src[v6 + 2] = base64_table[(4 * (a1[v5 + 1] & 0xF)) | (a1[v5 + 2] >> 6)];
v2 = v6 + 3;
v6 += 4;
src[v2] = base64_table[a1[v5 + 2] & 0x3F];
v5 += 3;
++v4;
}
if ( v8 == 1 )
{
src[v6] = base64_table[a1[v5] >> 2];
src[v6 + 1] = base64_table[16 * (a1[v5] & 3)];
strcat(src, "==");
}
else if ( v8 == 2 )
{
src[v6] = base64_table[a1[v5] >> 2];
src[v6 + 1] = base64_table[(16 * (a1[v5] & 3)) | (a1[v5 + 1] >> 4)];
src[v6 + 2] = base64_table[4 * (a1[v5 + 1] & 0xF)];
src[v6 + 3] = 61;
}
strcpy(a1, src);
return a1;
}
__int64 O_OLookAtYou()
{
__int64 result; // rax
char v1; // [rsp+1h] [rbp-5h]
int i; // [rsp+2h] [rbp-4h]
for ( i = 0; i <= 9; ++i )
{
v1 = base64_table[i];
base64_table[i] = base64_table[19 - i];
result = 19 - i;
base64_table[result] = v1;
}
return result;
}
换表base64
import base64
encodestr = 'd2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=='
s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
changetable = list(s)
for i in range(10):
changetable[i], changetable[19 - i] = changetable[19 - i], changetable[i]
changestr = ''.join(changetable)
trans_encodestr = encodestr.translate(str.maketrans(changestr,s))
flag = base64.b64decode(trans_encodestr)
print(flag)
[GWCTF 2019]xxor
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+8h] [rbp-68h]
int j; // [rsp+Ch] [rbp-64h]
__int64 v6[6]; // [rsp+10h] [rbp-60h] BYREF
__int64 v7[6]; // [rsp+40h] [rbp-30h] BYREF
v7[5] = __readfsqword(0x28u);
puts("Let us play a game?");
puts("you have six chances to input");
puts("Come on!");
memset(v6, 0, 40);
for ( i = 0; i <= 5; ++i )
{
printf("%s", "input: ");
a2 = (char **)((char *)v6 + 4 * i);
__isoc99_scanf("%d", a2);
}
memset(v7, 0, 40);
for ( j = 0; j <= 2; ++j )
{
dword_601078 = v6[j];
dword_60107C = HIDWORD(v6[j]);
a2 = (char **)&unk_601060;
sub_400686(&dword_601078, &unk_601060);
LODWORD(v7[j]) = dword_601078;
HIDWORD(v7[j]) = dword_60107C;
}
if ( (unsigned int)sub_400770(v7, a2) != 1 )
{
puts("NO NO NO~ ");
exit(0);
}
puts("Congratulation!\n");
puts("You seccess half\n");
puts("Do not forget to change input to hex and combine~\n");
puts("ByeBye");
return 0LL;
}
__int64 __fastcall sub_400770(_DWORD *a1)
{
if ( a1[2] - a1[3] == 2225223423LL
&& a1[3] + a1[4] == 4201428739LL
&& a1[2] - a1[4] == 1121399208LL
&& *a1 == -548868226
&& a1[5] == -2064448480
&& a1[1] == 550153460 )
{
puts("good!");
return 1LL;
}
else
{
puts("Wrong!");
return 0LL;
}
}
__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
__int64 result; // rax
unsigned int v3; // [rsp+1Ch] [rbp-24h]
unsigned int v4; // [rsp+20h] [rbp-20h]
int v5; // [rsp+24h] [rbp-1Ch]
unsigned int i; // [rsp+28h] [rbp-18h]
v3 = *a1;
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 0x3F; ++i )
{
v5 += 1166789954;
v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}
校验函数是由24字节的数据构成的方程组, 可以用z3解出, 加密的过程是处理相邻的两个字节64轮, 可以直接通过逆过程还原回去
from z3 import *
a0, a1, a2, a3, a4, a5 = Ints('a0 a1 a2 a3 a4 a5')
s = Solver()
s.add(a2 - a3 == 2225223423)
s.add(a3 + a4 == 4201428739)
s.add(a2 - a4 == 1121399208)
s.add(a0 == -548868226)
s.add(a5 == -2064448480)
s.add(a1 == 550153460)
if s.check() == sat:
print(s.model())
else:
print('no solution')
'''
[a2 = 3774025685,
a1 = 550153460,
a5 = -2064448480,
a0 = -548868226,
a3 = 1548802262,
a4 = 2652626477]
'''
REV
#include <stdlib.h>
#include <iostream>
using namespace std;
/*
[a2 = 3774025685,
a1 = 550153460,
a5 = -2064448480,
a0 = -548868226,
a3 = 1548802262,
a4 = 2652626477]
v3 = *a1;
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 63; ++i )
{
v5 += 0x458BCD42;
v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
}
*/
int main() {
unsigned int encodedata[6] = {(unsigned int)-548868226, \
550153460, 3774025685, 1548802262, 2652626477, (unsigned int)-2064448480};
unsigned int parameters[4] = {2, 2, 3, 4};
int flag[6] = {};
for (int i = 0; i < 6; i += 2) {
int v5 = 0x458BCD42 * 64;
unsigned int v4 = encodedata[i + 1];
unsigned int v3 = encodedata[i];
for (int j = 0; j < 64; ++j) {
v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + parameters[2]) ^ ((v3 >> 9) + parameters[3]) ^ 0x10;
v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + parameters[0]) ^ ((v4 >> 9) + parameters[1]) ^ 0x20;
v5 -= 0x458BCD42;
}
flag[i] = v3;
flag[i + 1] = v4;
}
for (int i = 0; i < 6; ++i) {
// little endian print for each int
// *((char *)&flag[i] + 3) == '\0'
cout << *((char *)&flag[i] + 2) << *((char *)&flag[i] + 1);
cout << *(char *)&flag[i];
}
cout << endl;
}
[FlareOn4]IgniteMe
void __noreturn start()
{
DWORD NumberOfBytesWritten; // [esp+0h] [ebp-4h] BYREF
NumberOfBytesWritten = 0;
hFile = GetStdHandle(0xFFFFFFF6);
dword_403074 = GetStdHandle(0xFFFFFFF5);
WriteFile(dword_403074, aG1v3M3T3hFl4g, 0x13u, &NumberOfBytesWritten, 0);
sub_4010F0(NumberOfBytesWritten);
if ( sub_401050() )
WriteFile(dword_403074, aG00dJ0b, 0xAu, &NumberOfBytesWritten, 0);// success
else
WriteFile(dword_403074, aN0tT00H0tRWe7r, 0x24u, &NumberOfBytesWritten, 0);
ExitProcess(0);
}
int testfunc()
{
int v1; // [esp+0h] [ebp-Ch]
int i; // [esp+4h] [ebp-8h]
unsigned int j; // [esp+4h] [ebp-8h]
char v4; // [esp+Bh] [ebp-1h]
v1 = getlength((int)inputs);
v4 = func_ROL4_divi2();
for ( i = v1 - 1; i >= 0; --i )
{
processed_values[i] = v4 ^ inputs[i];
v4 = inputs[i];
}
for ( j = 0; j < 39; ++j )
{
if ( processed_values[j] != (unsigned __int8)testdata[j] )
return 0;
}
return 1;
}
输入的串长40, v4是初值通过循环移位处理得到, 然后每位前后异或处理后, 与testdata数组校验
#include <iostream>
using namespace std;
int main() {
char testdata[] = {
'\r',
'&',
'I',
'E',
'*',
'\x17',
'x',
'D',
'+',
'l',
']',
'^',
'E',
'\x12',
'/',
'\x17',
'+',
'D',
'o',
'n',
'V',
'\t',
'_',
'E',
'G',
's',
'&',
'\n',
'\r',
'\x13',
'\x17',
'H',
'B',
'\x01',
'@',
'M',
'\f',
'\x02',
'i',
'\0'
};
// cout << sizeof(testdata) << endl;
char flag[40] = {};
char v4 = 4;
for (int i = 39; i >= 0; --i) {
flag[i] = v4 ^ testdata[i];
v4 = flag[i];
}
flag[39] = 0;
cout << "flag{" << flag << "}" << endl;
}
[WUSTCTF2020]Cr0ssfun
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[48]; // [rsp+0h] [rbp-30h] BYREF
puts(" _ _ _ _ _____ _____ _____ ");
puts("| | | | | | / ___|_ _| / ___| ");
puts("| | | | | | \\ `--. | | \\ `--. ___ ___ ");
puts("| |/\\| | | | |`--. \\ | | `--. \\/ _ \\/ __|");
puts("\\ /\\ / |_| /\\__/ / | | /\\__/ / __/ (__ ");
puts(" \\/ \\/ \\___/\\____/ \\_/ \\____/ \\___|\\___|");
while ( 1 )
{
puts("Input the flag");
__isoc99_scanf("%s", v4);
if ( (unsigned int)check(v4) == 1 )
break;
puts("0ops, your flag seems fake.");
puts("==============================");
rewind(_bss_start);
}
puts("Your flag is correct, go and submit it!");
return 0;
}
_BOOL8 __fastcall iven_is_handsome(_BYTE *a1)
{
return a1[10] == 112
&& a1[13] == 64
&& a1[3] == 102
&& a1[26] == 114
&& a1[20] == 101
&& (unsigned int)iven_is_c0ol(a1);
}
_BOOL8 __fastcall iven_is_c0ol(_BYTE *a1)
{
return a1[7] == 48
&& a1[16] == 95
&& a1[11] == 112
&& a1[23] == 101
&& a1[30] == 117
&& (unsigned int)iven_1s_educated(a1);
}
_BOOL8 __fastcall iven_1s_educated(_BYTE *a1)
{
return *a1 == 119 && a1[6] == 50 && a1[22] == 115 && a1[31] == 110 && a1[12] == 95 && (unsigned int)iven_1s_brave(a1);
}
_BOOL8 __fastcall iven_1s_brave(_BYTE *a1)
{
return a1[15] == 100
&& a1[8] == 123
&& a1[18] == 51
&& a1[28] == 95
&& a1[21] == 114
&& (unsigned int)iven_1s_great(a1);
}
_BOOL8 __fastcall iven_1s_great(_BYTE *a1)
{
return a1[2] == 116
&& a1[9] == 99
&& a1[32] == 125
&& a1[19] == 118
&& a1[5] == 48
&& a1[14] == 110
&& (unsigned int)iven_and_grace(a1);
}
_BOOL8 __fastcall iven_and_grace(_BYTE *a1)
{
return a1[4] == 50 && a1[17] == 114 && a1[29] == 102 && a1[17] == 114 && a1[24] == 95 && (unsigned int)finally_fun(a1);
}
_BOOL8 __fastcall finally_fun(_BYTE *a1)
{
return a1[1] == 99 && a1[25] == 64 && a1[27] == 101;
}
整理一下即可得到flag
[FlareOn6]Overlong
int __stdcall start(int a1, int a2, int a3, int a4)
{
char Text[128]; // [esp+0h] [ebp-84h] BYREF
int v6; // [esp+80h] [ebp-4h]
v6 = process(Text, &unk_402008, 28);
Text[v6] = 0;
MessageBoxA(0, Text, Str_output, 0);
return 0;
}
int __cdecl sub_401000(_BYTE *a1, char *a2)
{
int v3; // [esp+0h] [ebp-8h]
char v4; // [esp+4h] [ebp-4h]
if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
{
v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
v3 = 4;
}
else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
{
v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
v3 = 3;
}
else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
{
v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
v3 = 2;
}
else
{
v4 = *a2;
v3 = 1;
}
*a1 = v4;
return v3;
}
sub_401000
是解密函数, 0x00402008
是解密的data, 直接rev
#include <stdlib.h>
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int decode(unsigned char *dechar, unsigned char *val)
{
int ret; // [esp+0h] [ebp-8h]
unsigned char v4; // [esp+4h] [ebp-4h]
if ( (int)(unsigned char)*val >> 3 == 30 )
{
v4 = val[3] & 0x3F | ((val[2] & 0x3F) << 6);
ret = 4;
}
else if ( (int)(unsigned char)*val >> 4 == 14 )
{
v4 = val[2] & 0x3F | ((val[1] & 0x3F) << 6);
ret = 3;
}
else if ( (int)(unsigned char)*val >> 5 == 6 )
{
v4 = val[1] & 0x3F | ((*val & 0x1F) << 6);
ret = 2;
}
else
{
v4 = *val;
ret = 1;
}
*dechar = v4;
return ret;
}
int main()
{
unsigned char values[] =
{
224, 129, 137, 192, 160, 193, 174, 224, 129, 165,
193, 182, 240, 128, 129, 165, 224, 129, 178, 240,
128, 128, 160, 224, 129, 162, 114, 111, 193, 171,
101, 224, 128, 160, 224, 129, 180, 224, 129, 168,
193, 165, 32, 193, 165, 224, 129, 174, 99, 193,
175, 224, 129, 164, 240, 128, 129, 169, 110, 193,
167, 192, 186, 32, 73, 240, 128, 129, 159, 193,
161, 193, 159, 193, 141, 224, 129, 159, 193, 180,
240, 128, 129, 159, 240, 128, 129, 168, 193, 159,
240, 128, 129, 165, 224, 129, 159, 193, 165, 224,
129, 159, 240, 128, 129, 174, 193, 159, 240, 128,
129, 131, 193, 159, 224, 129, 175, 224, 129, 159,
193, 132, 95, 224, 129, 169, 240, 128, 129, 159,
110, 224, 129, 159, 224, 129, 167, 224, 129, 128,
240, 128, 129, 166, 240, 128, 129, 172, 224, 129,
161, 193, 178, 193, 165, 240, 128, 128, 173, 240,
128, 129, 175, 110, 192, 174, 240, 128, 129, 163,
111, 240, 128, 129, 173, 0
};
int length = sizeof(values) / sizeof(char);
string flag = "";
unsigned char tmp = '\0';
for (int i = 0; i < length; ++i)
{
decode(&tmp, &values[i]);
if (isalnum(tmp) || ispunct(tmp))
flag += tmp;
}
cout << flag << endl;
}
[FlareOn3]Challenge1
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Buffer[128]; // [esp+0h] [ebp-94h] BYREF
char *Str1; // [esp+80h] [ebp-14h]
char *Str2; // [esp+84h] [ebp-10h]
HANDLE StdHandle; // [esp+88h] [ebp-Ch]
HANDLE hFile; // [esp+8Ch] [ebp-8h]
DWORD NumberOfBytesWritten; // [esp+90h] [ebp-4h] BYREF
hFile = GetStdHandle(0xFFFFFFF5);
StdHandle = GetStdHandle(0xFFFFFFF6);
Str2 = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q";
WriteFile(hFile, "Enter password:\r\n", 0x12u, &NumberOfBytesWritten, 0);
ReadFile(StdHandle, Buffer, 0x80u, &NumberOfBytesWritten, 0);
Str1 = (char *)sub_401260(Buffer, NumberOfBytesWritten - 2);
if ( !strcmp(Str1, Str2) )
WriteFile(hFile, "Correct!\r\n", 0xBu, &NumberOfBytesWritten, 0);
else
WriteFile(hFile, "Wrong password\r\n", 0x11u, &NumberOfBytesWritten, 0);
return 0;
}
_BYTE *__cdecl sub_401260(int a1, unsigned int a2)
{
int v3; // [esp+Ch] [ebp-24h]
int v4; // [esp+10h] [ebp-20h]
int v5; // [esp+14h] [ebp-1Ch]
int i; // [esp+1Ch] [ebp-14h]
unsigned int v7; // [esp+20h] [ebp-10h]
_BYTE *v8; // [esp+24h] [ebp-Ch]
int v9; // [esp+28h] [ebp-8h]
int v10; // [esp+28h] [ebp-8h]
unsigned int v11; // [esp+2Ch] [ebp-4h]
v8 = malloc(4 * ((a2 + 2) / 3) + 1);
if ( !v8 )
return 0;
v11 = 0;
v9 = 0;
while ( v11 < a2 )
{
v5 = *(unsigned __int8 *)(v11 + a1);
if ( ++v11 >= a2 )
{
v4 = 0;
}
else
{
v4 = *(unsigned __int8 *)(v11 + a1);
++v11;
}
if ( v11 >= a2 )
{
v3 = 0;
}
else
{
v3 = *(unsigned __int8 *)(v11 + a1);
++v11;
}
v7 = v3 + (v5 << 16) + (v4 << 8);
v8[v9] = byte_413000[(v7 >> 18) & 0x3F];
v10 = v9 + 1;
v8[v10] = byte_413000[(v7 >> 12) & 0x3F];
v8[++v10] = byte_413000[(v7 >> 6) & 0x3F];
v8[++v10] = byte_413000[v3 & 0x3F];
v9 = v10 + 1;
}
for ( i = 0; i < dword_413040[a2 % 3]; ++i )
v8[4 * ((a2 + 2) / 3) - i - 1] = 61;
v8[4 * ((a2 + 2) / 3)] = 0;
return v8;
}
变表base64
import base64
encodestr = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"
changebase64 = "ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
originbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
trans_encodestr = encodestr.translate(str.maketrans(changebase64, originbase64))
flag = base64.b64decode(trans_encodestr)
print(flag)