一些比较有意思的题

实际上最近的比赛都有在打,只是没有整理了,一方面是时间不够,二是觉得做起的题的难度也就那样,没必要整理,就把最近感觉比较有含金量的题整理整理。最近也在出题,好忙。。。不过值得高兴的是,原本以为之前打的两个比赛已经没什么希望了,结果一个还有奖金,一个还进了线下,昨天永劫无间还用免费宝箱开了个冰魄皮肤,哈哈哈,欧皇竟是我自己。

这篇文章就整理最近觉得比较好的题。

HaHaHaHa

比赛时,搞了一个下午,java爆破太慢了。

先下载apk打开看看,发现是要输入8个字符串,然后没有小写字符。

用jeb打开。

发现使用了一个for循环来处理8个字符串。

然后下面有一个处理字符串的函数,也就是a类中的c函数。

然后下面使用修改后的数据去进行各种hash加密。

接下来看如何通过传入的第一个参数从而决定到底是哪种hash。

然后直接去解就会发现不对劲,原来是在开始的时候,修改了a类中的数据。

然后先得到8个字符串的加密方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

int[] b;
int i;
b = new int[]{0xAF, 0xA1, 0xA4, 170, 0xA5, 0xAE, 0xA0, 0xA3};
for(i=0;i<b.length;i++)
{
System.out.print(b[i]);
System.out.print(" ");
System.out.print((b[i]^0xab) >>> 3 & 1);
System.out.print(" ");
System.out.println((b[i]^0xab)&7);

}


// 0 4 SHA-256 fc7466e55fbf37b1
// 1 2 HmacSha512 78b0be39e63b6837
// 1 7 HmacSha512 c2f9c805d0442203
// 0 1 MD5 c11a61bb60d79dab
// 1 6 HmacSha512 869e650ee55bd9f6
// 0 5 SHA-384 f2dda5fc021fe2bf
// 1 3 HmacSha512 305044db48fe6174
// 1 0 HmacSha512 d6659b5e2d1059f8

然后开始解。

1
2
3
4
5
6
7
8
9
10
11
12
13

import hashlib

for a in range(0,128):
for b in range(0,128):
for c in range(0,128):
for d in range(0,128):
str = chr(a)+chr(b)+chr(c)+chr(d)
print(str)
flag = hashlib.sha384(str.encode('utf-8')).hexdigest()
if flag[0:16] == 'f2dda5fc021fe2bf':
print(str, end='')
exit(0)

HmacSha512比较特殊,就直接用了类中的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

package com.company;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class Main {

public static void main(String[] args) {
byte[][] a;
String[] c;
a = new byte[][]{"WIgD1ZNZ0ilJqFpw".getBytes(), "4811tjOZjoiXpjdq".getBytes(), "ALFjcgztxnUaC89v".getBytes(), "ZgHzTu79Zwhoi0PB".getBytes(), "UYBfajKYrDFE1zJs".getBytes(), "yr4PBIjlJg89FpP3".getBytes(), "SFHqaTYDf7EeEevX".getBytes(), "gUwrqaE3nCxKr4Du".getBytes()};
c = new String[]{"fc7466e55fbf37b1", "78b0be39e63b6837", "c2f9c805d0442203", "c11a61bb60d79dab", "869e650ee55bd9f6", "f2dda5fc021fe2bf", "305044db48fe6174", "d6659b5e2d1059f8"};
int v4 = 0;
MessageDigest hhh = null;
while(v4 < a.length) {
System.out.print(" ");
try {
hhh = MessageDigest.getInstance("MD5");
}
catch(NoSuchAlgorithmException v1_1) {
v1_1.printStackTrace();
}

hhh.update(a[v4]);
a[v4] = hhh.digest();
System.out.println(a[v4]);
++v4;
}

String v0_1;
byte[] s;
int a1, a2, a3, a4, calc = 0;
s = new byte[]{0x1, 0x2, 0x3, 0x4};

for (a1 = 71; a1 < 127; a1++) {
for (a2 = 65; a2 < 127; a2++) {
for (a3 = 76; a3 < 127; a3++) {
for (a4 =70; a4 < 127; a4++) {
s[0] = (byte) a1;
s[1] = (byte) a2;
s[2] = (byte) a3;
s[3] = (byte) a4;

v0_1 = func(s, a[0]);
System.out.println("no " + s[0] + " " + s[1] + " " + s[2] + " " + s[3] + " " + v0_1.substring(0, 16) + " " + c[2]);

if (v0_1.substring(0, 16).equals(c[7])) {
System.out.println("yes");
for (int i = 0; i < 4; i++) {
System.out.print(s[i]+" ");
}
System.exit(0);

}


}
}
}
}





int[] b;
int i;
b = new int[]{0xAF, 0xA1, 0xA4, 170, 0xA5, 0xAE, 0xA0, 0xA3};
for(i=0;i<b.length;i++)
{
System.out.print(b[i]);
System.out.print(" ");
System.out.print((b[i]^0xab) >>> 3 & 1);
System.out.print(" ");
System.out.println((b[i]^0xab)&7);

}

// 0 4 SHA-256 fc7466e55fbf37b1
// 1 2 HmacSha512 78b0be39e63b6837
// 1 7 HmacSha512 c2f9c805d0442203
// 0 1 MD5 c11a61bb60d79dab
// 1 6 HmacSha512 869e650ee55bd9f6
// 0 5 SHA-384 f2dda5fc021fe2bf
// 1 3 HmacSha512 305044db48fe6174
// 1 0 HmacSha512 d6659b5e2d1059f8
}
public static String func(byte[] arg2, byte[] arg3) {
String v0 = "HmacSha512";
String v2_2 = null;
try {
SecretKeySpec v1 = new SecretKeySpec(arg3, v0);
Mac v3 = Mac.getInstance(v0);
v3.init(((Key) v1));
v3.update(arg2);
for (v2_2 = new BigInteger(1, v3.doFinal()).toString(16); v2_2.length() < 0x20; v2_2 = "0" + v2_2) {
}

} catch (InvalidKeyException v2) {
((GeneralSecurityException) v2).printStackTrace();
return null;

} catch (NoSuchAlgorithmException v2_1) {

return null;
}
return v2_2;

}
}

最后会得到8组数据。

0x5f,0x38,0x40,0x50,
0x35,0x31,0x5f,0x48,
0x7d,0x50,0x31,0x31,
0x7b,0x48,0x40,0x35,
0x43,0x5f,0x35,0x35,
0x50,0x31,0x4e,0x33,
0x33,0x48,0x37,0x5f,
0x47,0x41,0x4c,0x46,

这就设计到&0x7f的问题了。一些数需要加0x80,一些数有不需要,所以我直接手动控制,来得到那个v10,看哪种情况满足条件和题目中a.b数组会产生一样的效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

package com.company;
import java.util.*;

public class Main {

public static void main(String[] args) {
int v9;
int v10;
byte[] v7_1;
v7_1=new byte[]{0x47,0x41,0x4c,0x46};
v7_1[0]+=0x80;
// v7_1[1]+=0x80;
// v7_1[2]+=0x80;
// v7_1[3]+=0x80;

v9 = 0;
v10 = 0;
while(v9 < v7_1.length) {
v10 = v10 << 1 | (v7_1[v9] & 0x80) >>> 7;
v7_1[v9] = ((byte)(v7_1[v9] & 0x7F));

++v9;
}

System.out.println(v10);
System.out.print(v10 >>> 3 & 1);
System.out.print(" ");
System.out.println(v10&7);

}
}

得到,输入后就会得到flag。

# 0x5f,0x38+0x80,0x40,0x50  5FB84050
#
# 0x35+0x80,0x31,0x5f+0x80,0x48  B531DF48
#
# 0x7d,0x50,0x31,0x31,  +0x80   FDD0B1B1
#
# 0x7b,0x48,0x40,0x35+0x80   7B4840B5
#
# 0x43+0x80,0x5f+0x80,0x35+0x80,0x35   C3DFB535
#
# 0x50,0x31+0x80,0x4e,0x33+0x80   50B14EB3
#
# 0x33+0x80,0x48,0x37+0x80,0x5f+0x80  B348B7DF
#
# 0x47+0x80,0x41,0x4c,0x46   C7414C46

fastjs

赛后来做的,这种题型已经是第三次见了,所以准备来搞一搞。

看雪,和Mas0n师傅的博客里面都有详细讲解如何解这种题。

看雪

Mas0n

实际上就是利用quickjs来将一个js文件弄成.c文件,然后将用gcc编译c文件成为exe。

比如说,GitHub上quickjs项目example的hello.js,弄成c文件后就是如下的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/* File generated automatically by the QuickJS compiler. */

#include "quickjs-libc.h"

const uint32_t qjsc_hello_size = ???;

const uint8_t qjsc_hello[size] = {

};

static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx = JS_NewContextRaw(rt);
if (!ctx)
return NULL;
JS_AddIntrinsicBaseObjects(ctx);
JS_AddIntrinsicDate(ctx);
JS_AddIntrinsicEval(ctx);
JS_AddIntrinsicStringNormalize(ctx);
JS_AddIntrinsicRegExp(ctx);
JS_AddIntrinsicJSON(ctx);
JS_AddIntrinsicProxy(ctx);
JS_AddIntrinsicMapSet(ctx);
JS_AddIntrinsicTypedArrays(ctx);
JS_AddIntrinsicPromise(ctx);
JS_AddIntrinsicBigInt(ctx);
return ctx;
}

int main(int argc, char **argv)
{
JSRuntime *rt;
JSContext *ctx;
rt = JS_NewRuntime();
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
ctx = JS_NewCustomContext(rt);
js_std_add_helpers(ctx, argc, argv);
js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0);
js_std_loop(ctx);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}

这和我们将题目文件拖到ida如出一辙。

然后我们采用文章中的方法来将题目的opcode弄成字节码。

得到,有点长,不贴完了。

0000:  02 3a                    58 atom indexes {
1"long2str"
1"str2long"
1"sdfsfsdf"
1"str2Hex"
1"hex2str"

···
···
···


put_loc0 0: “
get_var_undef arguments
typeof_is_undefined
if_true8 203
get_var arguments
dup
put_var args
put_loc0 0: “
goto8 215
203: push_atom_value error
dup
put_var args
put_loc0 0: “
215: get_var main
get_var args
call1 1
set_loc0 0: “
return

                            }

然后手搓还原,只不过也太多了,暂时不知道能用什么工具反编译不,实际上可以半猜半分析。

可以看到里面有base64表 推测base64加密,有dealt,有e,xxtea。

然后尝试去解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#include<stdio.h>

void decrypt(unsigned int *code ,unsigned int *key ,unsigned int n)
{
unsigned int next,end,sum;
unsigned int rounds,e,delta=2654435769;
int i;

rounds=6+52/n;
sum=rounds*delta;
next=code[0];//设置next为code的第一个
do
{
e=(sum>>2)&3;
for(i=n-1;i>0;i--)//解密最后一个到第二个
{
end=code[i-1];
code[i]-=(( (end>>5^next<<2) + (next>>3^end<<4) ) ^ ( (sum^next) + (key[(i&3)^e]^end) ));
next=code[i];
}
end=code[n-1];
code[0]-=(( (end>>5^next<<2) + (next>>3^end<<4) ) ^ ( (sum^next) +(key[i&3^e]^end) ));
next=code[0];
sum-=delta;
}while(--rounds);

}
int main()
{
unsigned int flag[2]={1,2},key[4]={0x745f6f6e, 0x676e6968, 0x5f73695f, 0x65757274};
unsigned int n=14;
unsigned int code[14]={0xced0ae05,0xb5801f44,0x4caf36bc,0xfc098569,0x71c9c36c,0xe53d3546,0xbe6a5ca9,0xa7d47fa0,0xd8320907,0x622dc36a,0x91a57286,0x2397e523,0xff5ddb31,0x627305e7};
int i;

decrypt(code,key,n);
printf("%x %x\n",code[0],code[1]);
for(i=0;i<14;i++)
{
printf("%c%c%c%c",*((char*)&code[i]+0),*((char*)&code[i]+1),*((char*)&code[i]+2),*((char*)&code[i]+3));
}

}
//ZmxhZ3tmYzVlMDM4ZDM4YTU3MDMyMDg1NDQxZTdmZTcwMTBiMH0=4

解下base64得到flag{fc5e038d38a57032085441e7fe7010b0}

showyourflag

初步分析可以知道,这个程序是加密文件,然后生成一个文件。

命令行参数

showyourflag [flie] [encoedfile]

当时和师傅一起做题时,只分析出来了部分,没分析完,可以确定是个png文件,但还需要分析那个主要加密函数,后面有时间来细致分析(看情况)。

gogogog

一个华容道的题,开始是蓝帽杯决赛的一个题,后面也遇到了两次,还是一模一样的。。。。所以直接秒了。

一个解华容道的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

#-*-coding:utf-8-*-

import heapq
import copy
import time
import math
import argparse

# 初始状态
# S0 = [[11, 9, 4, 15],
# [1, 3, 0, 12],
# [7, 5, 8, 6],
# [13, 2, 10, 14]]
S0 = [[5, 1, 0, 2],
[9, 6, 3, 8],
[13, 15, 10, 11],
[14, 4, 7, 12]]

# 目标状态
SG = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 0]]

# 上下左右四个方向移动
MOVE = {'up': [1, 0],
'down': [-1, 0],
'left': [0, -1],
'right': [0, 1]}

# OPEN表
OPEN = []

# 节点的总数
SUM_NODE_NUM = 0

# 状态节点
class State(object):
def __init__(self, deepth=0, rest_dis=0.0, state=None, hash_value=None, father_node=None):
'''
初始化
:参数 deepth: 从初始节点到目前节点所经过的步数
:参数 rest_dis: 启发距离
:参数 state: 节点存储的状态 4*4的列表
:参数 hash_value: 哈希值,用于判重
:参数 father_node: 父节点指针
'''
self.deepth = deepth
self.rest_dis = rest_dis
self.fn = self.deepth + self.rest_dis
self.child = [] # 孩子节点
self.father_node = father_node # 父节点
self.state = state # 局面状态
self.hash_value = hash_value # 哈希值

def __lt__(self, other): # 用于堆的比较,返回距离最小的
return self.fn < other.fn

def __eq__(self, other): # 相等的判断
return self.hash_value == other.hash_value

def __ne__(self, other): # 不等的判断
return not self.__eq__(other)


def cal_M_distence(cur_state):
'''
计算曼哈顿距离
:参数 state: 当前状态,4*4的列表, State.state
:返回: M_cost 每一个节点计算后的曼哈顿距离总和
'''
M_cost = 0
for i in range(4):
for j in range(4):
if cur_state[i][j] == SG[i][j]:
continue
num = cur_state[i][j]
if num == 0:
x, y = 3, 3
else:
x = num / 4 # 理论横坐标
y = num - 4 * x - 1 # 理论的纵坐标
M_cost += (abs(x - i) + abs(y - j))
return M_cost

def cal_E_distence(cur_state):
'''
计算曼哈顿距离
:参数 state: 当前状态,4*4的列表, State.state
:返回: M_cost 每一个节点计算后的曼哈顿距离总和
'''
E_cost = 0
for i in range(4):
for j in range(4):
if cur_state[i][j] == SG[i][j]:
continue
num = cur_state[i][j]
if num == 0:
x, y = 3, 3
else:
x = num / 4 # 理论横坐标
y = num - 4 * x - 1 # 理论的纵坐标
E_cost += math.sqrt((x - i)*(x - i) + (y - j)*(y - j))
return E_cost

def generate_child(sn_node, sg_node, hash_set, open_table, cal_distence):
'''
生成子节点函数
:参数 sn_node: 当前节点
:参数 sg_node: 最终状态节点
:参数 hash_set: 哈希表,用于判重
:参数 open_table: OPEN表
:参数 cal_distence: 距离函数
:返回: None
'''
if sn_node == sg_node:
heapq.heappush(open_table, sg_node)
print('已找到终止状态!')
return
for i in range(0, 4):
for j in range(0, 4):
if sn_node.state[i][j] != 0:
continue
for d in ['up', 'down', 'left', 'right']: # 四个偏移方向
x = i + MOVE[d][0]
y = j + MOVE[d][1]
if x < 0 or x >= 4 or y < 0 or y >= 4: # 越界了
continue
state = copy.deepcopy(sn_node.state) # 复制父节点的状态
state[i][j], state[x][y] = state[x][y], state[i][j] # 交换位置
h = hash(str(state)) # 哈希时要先转换成字符串
if h in hash_set: # 重复了
continue
hash_set.add(h) # 加入哈希表

# 记录扩展节点的个数
global SUM_NODE_NUM
SUM_NODE_NUM += 1

deepth = sn_node.deepth + 1 # 已经走的距离函数
rest_dis = cal_distence(state) # 启发的距离函数
node = State(deepth, rest_dis, state, h, sn_node) # 新建节点
sn_node.child.append(node) # 加入到孩子队列
heapq.heappush(open_table, node) # 加入到堆中

# show_block(state, deepth) # 打印每一步的搜索过程


def show_block(block, step):
print("------", step, "--------")
for b in block:
print(b)

def print_path(node):
'''
输出路径
:参数 node: 最终的节点
:返回: None
'''
print("最终搜索路径为:")
steps = node.deepth

stack = [] # 模拟栈
while node.father_node is not None:
stack.append(node.state)
node = node.father_node
stack.append(node.state)
step = 0
while len(stack) != 0:
t = stack.pop()
show_block(t, step)
step += 1
return steps


def A_start(start, end, distance_fn, generate_child_fn):
'''
A*算法
:参数 start: 起始状态
:参数 end: 终止状态
:参数 distance_fn: 距离函数,可以使用自定义的
:参数 generate_child_fn: 产生孩子节点的函数
:返回: 最优路径长度
'''
root = State(0, 0, start, hash(str(S0)), None) # 根节点
end_state = State(0, 0, end, hash(str(SG)), None) # 最后的节点
if root == end_state:
print("start == end !")

OPEN.append(root)
heapq.heapify(OPEN)

node_hash_set = set() # 存储节点的哈希值
node_hash_set.add(root.hash_value)
while len(OPEN) != 0:
top = heapq.heappop(OPEN)
if top == end_state: # 结束后直接输出路径
return print_path(top)
# 产生孩子节点,孩子节点加入OPEN表
generate_child_fn(sn_node=top, sg_node=end_state, hash_set=node_hash_set,
open_table=OPEN, cal_distence=distance_fn)
print("无搜索路径!") # 没有路径
return -1

if __name__ == '__main__':

# 可配置式运行文件
parser = argparse.ArgumentParser(description='选择距离计算方法')
parser.add_argument('--method', '-m', help='method 选择距离计算方法(cal_E_distence or cal_M_distence)', default = 'cal_M_distence')
args = parser.parse_args()
method = args.method

time1 = time.time()
if method == 'cal_E_distence':
length = A_start(S0, SG, cal_E_distence, generate_child)
else:
length = A_start(S0, SG, cal_M_distence, generate_child)
time2 = time.time()
if length != -1:
if method == 'cal_E_distence':
print("采用欧式距离计算启发函数")
else:
print("采用曼哈顿距离计算启发函数")
print("搜索最优路径长度为", length)
print("搜索时长为", (time2 - time1), "s")
print("共检测节点数为", SUM_NODE_NUM)

根据程序的方向,换一下,得到###$@%#$$@@@%#%#%@$@%##$$@@%##%#

1
2
3
4
5

table={'a':'$' ,'d':'%' ,'w':'@' ,'s':'#' }
s='sssawdsaawwwdsdsdwawdssaawwdssds'
for i in s:
print(table[i],end='')

然后md5加密。

Faker.exe

题目名称不叫Faker.exe,绿盟杯的一道500分的题,动态分可能更高,比赛时没做起,最后发现是脚本,我愚蠢的吧if判断条件后面加了个分号,低级错误,导致没能进线下,我是傻逼。

一道类似于病毒的题,以隐藏文件形式创建了个dll文件,并且在exe中用命令行执行来调用dll文件的导出函数,也就是cherk,传入的参数是26字节,也就是flag{}中间部分,然后进行了一些操作。

可以根据弹出的字符串和GetWindowsText函数来定位到关键位置。

接下来就会以隐藏模式创建FakerDll和Faker.dll文件。

接下来会自解密两个字符串,并将flag{}内的内容和两个字符串拼接起来。

我们来看看最后的字符串会变成什么样子。

1
2
3
4
5
6
7
8
9
10
11
12
13

s1="D;]Xjoepxt]TztXPX75]svoemm43/fyf GblfsEmm/emm-Difdl"
s2="D;]Xjoepxt]TztXPX75]svoemm43/fyf GblfsEmm/emm-Difdl"
for i in range(len(s1)):
print(chr(ord(s1[i])-1),end='')
print(end='\n')
for i in range(len(s2)):
print(chr(ord(s2[i])-1),end='')
print(end='\n')

# C:\Windows\SysWOW64\rundll32.exe FakerDll.dll,Check
# C:\Windows\SysWOW64\rundll32.exe FakerDll.dll,Check

然后拼接上flag,所以已经可以想到了,这个是想用windows自带的rundll32.exe来启动dll文件来检测flag是否正确,接下来,看sub_402680函数。

Faker.dll分析。

check函数

字符串处理函数

然后写脚本,先base64解,再异或,当然,因为个人的低级错误,分号的问题,导致没得到正确答案,也是非常可惜。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#include<stdio.h>
#include<string.h>

//C:\Windows\SysWOW64\rundll32.exe FakerDll.dll,Check aa

int main()
{
char s3[]="sbVnXr_G`By<Dp]5gIUmGk6t4x";
int i,j;

for(i=0;i<13;i++)
{
if ( ((s3[i]^0xf ) <= 'z') && ( (s3[i]^ 0xf ) >= '0' ))
{
s3[i] ^= 0xf;
}

}

for(i=13;i<26;i++)
{
if ( ((s3[i]^5 ) <= 'z' )&& ( (s3[i]^5 ) >= '0' ))
{
s3[i] ^= 5;
}

}

for(i=0;i<26;i++)
{
printf("%c",s3[i]);
}
}
//smYaWrPHoMv3KuX0bLPhBn3q1x