1
unit
MainFrm;
2
3
interface
4
5
uses
6
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7
Dialogs, StdCtrls, Mask, RzEdit, ExtCtrls,PN_ThreadPool,PNHttp,PNCE_GlbFun,
8
PerlRegEx;
9
10
type
11
TMainForm
=
class
(TForm)
12
grp1: TGroupBox;
13
bvl1: TBevel;
14
Input1: TRzEdit;
15
grp2: TGroupBox;
16
bvl2: TBevel;
17
Input2: TRzEdit;
18
grp3: TGroupBox;
19
bvl3: TBevel;
20
Input3: TRzEdit;
21
img1: TImage;
22
img2: TImage;
23
img3: TImage;
24
grp4: TGroupBox;
25
bvl4: TBevel;
26
img4: TImage;
27
Input4: TRzEdit;
28
grp5: TGroupBox;
29
bvl5: TBevel;
30
img5: TImage;
31
Input5: TRzEdit;
32
grp6: TGroupBox;
33
bvl6: TBevel;
34
img6: TImage;
35
Input6: TRzEdit;
36
grp7: TGroupBox;
37
bvl7: TBevel;
38
img7: TImage;
39
Input7: TRzEdit;
40
grp8: TGroupBox;
41
bvl8: TBevel;
42
img8: TImage;
43
Input8: TRzEdit;
44
grp9: TGroupBox;
45
bvl9: TBevel;
46
img9: TImage;
47
Input9: TRzEdit;
48
btn1: TButton;
49
RegNum: TEdit;
50
procedure
FormCreate(Sender: TObject);
51
procedure
FormDestroy(Sender: TObject);
52
procedure
Input1KeyPress(Sender: TObject;
var
Key: Char);
53
procedure
btn1Click(Sender: TObject);
54
private
55
{
Private declarations
}
56
public
57
{
Public declarations
}
58
procedure
DownProcessRequest(Sender: TPNThreadPool;
59
aDataObj: TPNTaskObject; aThread: TPNPoolThread);
60
end
;
61
62
TCoding
=
record
63
Status: integer;
//
忙碌1,空闲0,等待用户输入数据2,用户已经输入,等待处理3
64
ShowBegin: integer;
//
开始显示验证码的时间
65
end
;
66
67
///
线程池中的线程处理类,可以派生,也可以不用派生
68
TRegThread
=
class
(TPNPoolThread)
69
private
70
MyCodeIdx: integer;
71
bmp: TBitmap;
72
procedure
ShowImg1;
73
procedure
ShowImg;
74
public
75
destructor
Destroy;
76
end
;
77
78
TRegData
=
class
(TPNTaskObject)
79
private
80
FId: String;
//
编号
81
public
82
constructor
Create(
const
AId:
string
);
83
function
Duplicate(DataObj: TPNTaskObject;
84
const
Processing: Boolean): Boolean;
///
判断两个任务是否重复,此函数必须在派生类写明
85
function
Info:
string
;
override
;
///
输出信息,覆盖
86
end
;
87
88
var
89
MainForm: TMainForm;
90
Codings:
array
[
1
..
9
]
of
TCoding;
91
CodingCs: TPNCriticalSection;
///
申请打码资源的CS
92
93
RegId: integer;
94
95
StrLog:
string
;
///
日志数据
96
PoolReg: TPNThreadPool;
///
线程池
97
csLog: TPNCriticalSection;
///
保存日志的临界区
98
99
function
CodingApply: integer;
//
申请打码显示资源,如果申请成功,返回显示的标号,否则返回
-
1
100
function
CodingRelease(CodeIdx: Integer):
string
;
//
释放显示资源,返回的是打码的信息
101
function
CodingWait(CodeIdx: Integer): Boolean;
//
将状态更改为等待
102
function
CodingOK(CodeIdx: Integer): Boolean;
//
将状态更改为处理完毕
103
function
CodingStatus(CodeIdx: Integer): integer;
//
获取当前状态
104
105
implementation
106
107
{
$R *.dfm
}
108
109
function
CodingApply: integer;
110
var
111
i: integer;
112
begin
113
CodingCs.Enter;
114
Result:
=
-
1
;
115
try
116
for
i :
=
1
to
9
do
begin
117
if
Codings[i].Status
=
0
then
begin
118
Result:
=
i;
119
Codings[i].Status:
=
1
;
120
Break;
121
end
;
122
end
;
123
finally
124
CodingCs.Leave;
125
Sleep(
0
);
126
end
;
127
end
;
128
129
function
CodingRelease(CodeIdx: Integer):
string
;
130
begin
131
if
(CodeIdx
<
0
)
or
(CodeIdx
>
9
)
then
Exit;
132
CodingCs.Enter;
133
try
134
try
135
Result:
=
TEdit(MainForm.FindComponent(
'
Input
'
+
IntToStr(CodeIdx))).Text;
136
except
137
Result:
=
''
;
138
end
;
139
Codings[CodeIdx].Status:
=
0
;
140
finally
141
CodingCs.Leave;
142
Sleep(
0
);
143
end
;
144
end
;
145
146
function
CodingWait(CodeIdx: Integer): Boolean;
147
begin
148
if
(CodeIdx
<
0
)
or
(CodeIdx
>
9
)
then
Exit;
149
Result:
=
True;
150
CodingCs.Enter;
151
try
152
try
153
Codings[CodeIdx].Status:
=
2
;
154
except
155
Result:
=
False;
156
end
;
157
finally
158
CodingCs.Leave;
159
Sleep(
0
);
160
end
;
161
end
;
162
163
function
CodingOK(CodeIdx: Integer): Boolean;
164
begin
165
if
(CodeIdx
<
0
)
or
(CodeIdx
>
9
)
then
Exit;
166
Result:
=
True;
167
CodingCs.Enter;
168
try
169
try
170
Codings[CodeIdx].Status:
=
3
;
171
except
172
Result:
=
False;
173
end
;
174
finally
175
CodingCs.Leave;
176
Sleep(
0
);
177
end
;
178
end
;
179
function
CodingStatus(CodeIdx: Integer): integer;
180
begin
181
if
(CodeIdx
<
0
)
or
(CodeIdx
>
9
)
then
Exit;
182
CodingCs.Enter;
183
try
184
Result:
=
Codings[CodeIdx].Status;
185
finally
186
CodingCs.Leave;
187
Sleep(
0
);
188
end
;
189
end
;
190
191
constructor
TRegData.Create(
const
AId:
string
);
192
begin
193
FId:
=
AId;
194
end
;
195
196
function
TRegData.Duplicate(DataObj: TPNTaskObject;
197
const
Processing: Boolean): Boolean;
198
begin
199
Result :
=
(
not
Processing)
and
200
(FId
=
TRegData(DataObj).FId);
201
end
;
202
203
function
TRegData.Info:
string
;
204
begin
205
Result:
=
'
FId=
'
+
FId
+
'
;
'
;
206
end
;
207
208
209
procedure
TRegThread.ShowImg1;
210
begin
211
try
212
TImage(MainForm.FindComponent(
'
Img
'
+
IntToStr(MyCodeIdx))).Picture.Assign(bmp);
213
TEdit(MainForm.FindComponent(
'
Input
'
+
IntToStr(MyCodeIdx))).Text:
=
''
;
214
except
215
end
;
216
CodingWait(MyCodeIdx);
217
end
;
218
procedure
TRegThread.ShowImg;
219
begin
220
Synchronize(ShowImg1);
221
end
;
222
destructor
TRegThread.Destroy;
223
begin
224
try
225
if
bmp
<>
nil
then
bmp.Free;
226
except
227
end
;
228
inherited
Destroy;
229
end
;
230
231
function
HexToInt(
const
S: String): DWORD;
232
asm
233
PUSH EBX
234
PUSH ESI
235
236
MOV ESI, EAX
//
字符串地址
237
MOV EDX, [EAX
-
4
]
//
读取字符串长度
238
239
XOR EAX, EAX
//
初始化返回值
240
XOR ECX, ECX
//
临时变量
241
242
TEST ESI, ESI
//
判断是否为空指针
243
JZ @@
2
244
TEST EDX, EDX
//
判断字符串是否为空
245
JLE @@
2
246
MOV BL, $
20
247
@@
0
:
248
MOV CL, [ESI]
249
INC ESI
250
251
OR CL, BL
//
如果有字母则被转换为小写字母
252
SUB CL,
'
0
'
253
JB @@
2
//
<
'
0
'
的字符
254
CMP CL, $
09
255
JBE @@
1
//
'
0
'
..
'
9
'
的字符
256
SUB CL,
'
a
'
-
'
0
'
-
10
257
CMP CL, $0A
258
JB @@
2
//
<
'
a
'
的字符
259
CMP CL, $0F
260
JA @@
2
//
>
'
f
'
的字符
261
@@
1
:
//
'
0
'
..
'
9
'
,
'
A
'
..
'
F
'
,
'
a
'
..
'
f
'
262
SHL EAX,
4
263
OR EAX, ECX
264
DEC EDX
265
JNZ @@
0
266
JMP @@
3
267
@@
2
:
268
XOR EAX, EAX
//
非法16进制字符串
269
@@
3
:
270
POP ESI
271
POP EBX
272
RET
273
end
;
274
275
procedure
TMainForm.DownProcessRequest(Sender: TPNThreadPool;
276
aDataObj: TPNTaskObject; aThread: TPNPoolThread);
277
var
278
Http: TPNHttp;
279
i,j,LBase,IdxA,IdxB: integer;
280
RndStr,FormParams,StrResult,StrQQ,StrCookie,StrIP:
string
;
281
SListA,SListB: TStringList;
282
Reg: TPerlRegEx;
283
ParamArray:
array
[
0
..
14
]
of
string
;
284
begin
285
//
FPNWriteLnText(
'
日志.txt
'
,TRegData(aDataObj).FId
+
'
开始注册
'
,False);
286
Http:
=
TPNHttp.Create(
nil
,True,True);
287
Randomize;
288
StrIP:
=
'
1.193.86.
'
+
IntToStr(Random(
255
)
+
1
);
289
//
StrIP:
=
IntToStr(Random(
255
)
+
1
)
+
'
.
'
+
IntToStr(Random(
255
)
+
1
)
+
'
.
'
+
IntToStr(Random(
255
)
+
1
)
+
'
.
'
+
IntToStr(Random(
255
)
+
1
);
290
Http.Request.CustomHeaders.Add(
'
X-Forwarded-For:
'
+
StrIP);
291
with
Http.ProxyParams
do
begin
292
ProxyServer:
=
''
;
//
代理地址
293
ProxyPort:
=
80
;
//
端口
294
ProxyUsername:
=
''
;
//
代理登录用户名
295
ProxyPassword:
=
''
;
//
代理登录密码
296
end
;
297
try
298
try
299
Http.HttpGet(
'
http://reg.qq.com/
'
);
300
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
HEADER信息.txt
'
,
'
首页:
'
+
Http.HttpHeader,False);
301
TRegThread(aThread).MyCodeIdx:
=
CodingApply;
302
///
等待获取打码资源
303
while
TRegThread(aThread).MyCodeIdx
=-
1
do
begin
304
sleep(
500
);
305
if
not
aThread.Terminated
then
306
TRegThread(aThread).MyCodeIdx:
=
CodingApply
307
else
308
exit;
309
end
;
310
try
311
TRegThread(aThread).Bmp:
=
Http.HttpBmp(
'
http://captcha.qq.com/getimage?aid=1007901&0.9408595752591837
'
);
312
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
HEADER信息.txt
'
,
'
验证码:
'
+
Http.HttpHeader,False);
313
TRegThread(aThread).ShowImg;
314
finally
315
if
TRegThread(aThread).Bmp
<>
nil
then
316
TRegThread(aThread).Bmp.Free;
317
end
;
318
while
CodingStatus(TRegThread(aThread).MyCodeIdx)
=
2
do
begin
319
Sleep(
200
);
320
if
aThread.Terminated
then
321
Exit;
322
end
;
323
RndStr:
=
CodingRelease(TRegThread(aThread).MyCodeIdx);
324
//
FPNWriteLnText(
'
日志.txt
'
,TRegData(aDataObj).FId
+
'
:RndStr=
'
+
RndStr,False);
325
FormParams:
=
Http.HttpGet(
'
http://reg.qq.com/cgi-bin/checkconn?seed0.8865932116432269
'
);
326
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
HEADER信息.txt
'
,
'
CheckConn:
'
+
Http.HttpHeader,False);
327
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
返回的参数集:
'
+
FormParams,False);
328
//
FormParams:
=
Copy(FormParams,
33
,
402
);
329
StrCookie:
=
Http.CookieMgr.CookieCollection.Cookie[
'
PCCOOKIE
'
,
'
qq.com
'
].Value;
330
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
PCCOOKIE值为:
'
+
StrCookie,False);
331
StrCookie:
=
copy(StrCookie,length(StrCookie)
-
1
,
2
);
332
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
LBASE值为:
'
+
StrCookie,False);
333
LBase:
=
HexToInt(StrCookie);
334
335
ParamArray[
0
]:
=
'
QQ
'
;
336
ParamArray[
1
]:
=
'
EMAIL
'
;
337
ParamArray[
2
]:
=
'
zeze
'
;
338
ParamArray[
3
]:
=
'
0
'
;
339
ParamArray[
4
]:
=
'
1985
'
;
340
ParamArray[
5
]:
=
'
1
'
;
341
ParamArray[
6
]:
=
'
2
'
;
342
ParamArray[
7
]:
=
'
1
'
;
343
ParamArray[
8
]:
=
'
2
'
;
344
ParamArray[
9
]:
=
'
abc111111
'
;
345
ParamArray[
10
]:
=
'
abc111111
'
;
346
ParamArray[
11
]:
=
'
1
'
;
347
ParamArray[
12
]:
=
'
11
'
;
348
ParamArray[
13
]:
=
'
1
'
;
349
ParamArray[
14
]:
=
RndStr;
350
try
351
SListA:
=
FPNSplit(Copy(FormParams,
33
,
402
),
'
,
'
);
352
SListB:
=
FPNSplit(Copy(FormParams,
447
,
64
),
'
,
'
);
353
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,Copy(FormParams,
447
,
64
),False);
354
FormParams:
=
''
;
355
for
i :
=
0
to
12
do
begin
356
IdxA:
=
StrToInt(SListB[i])
xor
LBase;
357
IdxB:
=
12
-
i;
358
IdxA:
=
IdxA
xor
6818
;
359
IdxA:
=
IdxA
xor
8315
;
360
IdxA:
=
IdxA
xor
5123
;
361
IdxA:
=
IdxA
xor
2252
;
362
for
j :
=
0
to
5
do
363
IdxA:
=
IdxA
xor
0
;
364
IdxA:
=
IdxA
mod
15
;
365
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
IdxA:
'
+
IntToStr(IdxA),False);
366
367
FormParams:
=
FormParams
+
Copy(SListA[IdxB],
2
,
28
)
+
'
=
'
+
ParamArray[IdxA]
+
'
&
'
368
end
;
369
370
//
FormParams:
=
Copy(SList[
0
],
2
,
28
)
+
'
=1&
'
+
Copy(SList[
1
],
2
,
28
)
+
'
=1&
'
+
Copy(SList[
2
],
2
,
28
)
+
'
=pop67579818&
'
371
//
+
Copy(SList[
3
],
2
,
28
)
+
'
=1983&
'
+
Copy(SList[
4
],
2
,
28
)
+
'
=
'
+
RndStr
+
'
&
'
+
Copy(SList[
5
],
2
,
28
)
+
'
=1&
'
372
//
+
Copy(SList[
6
],
2
,
28
)
+
'
=lovezeze&
'
+
Copy(SList[
7
],
2
,
28
)
+
'
=pop67579818&
'
+
Copy(SList[
8
],
2
,
28
)
+
'
=0&
'
373
//
+
Copy(SList[
9
],
2
,
28
)
+
'
=1&
'
+
Copy(SList[
10
],
2
,
28
)
+
'
=2&
'
+
Copy(SList[
11
],
2
,
28
)
+
'
=11&
'
374
//
+
Copy(SList[
12
],
2
,
28
)
+
'
=1
'
;
375
finally
376
SListA.Free;
377
SListB.Free;
378
end
;
379
for
i :
=
0
to
Http.CookieMgr.CookieCollection.Count
-
1
do
380
StrCookie:
=
StrCookie
+
Http.CookieMgr.CookieCollection.Items[i].CookieName
+
'
:
'
381
+
Http.CookieMgr.CookieCollection.Items[i].CookieText;
382
StrResult:
=
Http.HttpPost(
'
http://reg.qq.com/cgi-bin/getnum
'
,FormParams,True);
383
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
HEADER信息.txt
'
,
'
POST时候:
'
+
Http.HttpHeader,False);
384
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
提交COOKIE为:
'
+
StrCookie,False);
385
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
数据日志.txt
'
,
'
提交参数为:
'
+
FormParams,False);
386
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
返回数据.txt
'
,StrResult,False);
387
Reg:
=
TPerlRegEx.Create(
nil
);
388
try
389
Reg.Subject:
=
StrResult;
390
Reg.RegEx:
=
'
您获得的号码为:\<span id\=\"aq\-uin\" class\=\"number\">([\s\S]*?)\<
'
;
391
if
Reg.MatchAgain
then
begin
392
StrQQ:
=
Reg.SubExpressions[
1
];
393
FPNWriteLnText(
'
注册成功的QQ.txt
'
,StrQQ,False);
394
end
else
begin
395
FPNWriteLnText(
'
注册失败线程.txt
'
,TRegData(aDataObj).FId,False);
396
end
;
397
//
FPNWriteLnText(TRegData(aDataObj).FId
+
'
匹配结果.txt
'
,StrResult,False);
398
finally
399
Reg.Free;
400
end
;
401
except
402
403
end
;
404
finally
405
Http.Free;
406
end
;
407
end
;
408
409
procedure
TMainForm.btn1Click(Sender: TObject);
410
var
411
i: integer;
412
begin
413
for
i :
=
1
to
StrToInt(RegNum.Text)
do
begin
414
RegId:
=
RegId
+
1
;
415
PoolReg.AddRequest(TRegData.Create(IntToStr(RegId)));
416
end
;
417
end
;
418
419
procedure
TMainForm.FormCreate(Sender: TObject);
420
begin
421
RegId:
=
0
;
422
CodingCs:
=
TPNCriticalSection.Create;
423
PoolReg :
=
TPNThreadPool.Create(
nil
);
424
with
PoolReg
do
begin
425
OnProcessRequest :
=
DownProcessRequest;
///
线程处理函数
426
AdjustInterval :
=
5
*
1000
;
///
减少线程间隔时间,
5
秒
427
MinAtLeast :
=
False;
///
是否设置最小线程数
428
ThreadDeadTimeout :
=
10
*
1000
;
///
线程死亡超时时间
429
ThreadsMinCount :
=
10
;
///
最小线程数
430
ThreadsMaxCount :
=
50
;
///
最大线程数
431
uTerminateWaitTime :
=
2
*
1000
;
///
挂起等待时间
432
end
;
433
434
end
;
435
436
procedure
TMainForm.FormDestroy(Sender: TObject);
437
begin
438
PoolReg.Free;
439
CodingCs.Free;
440
end
;
441
442
procedure
TMainForm.Input1KeyPress(Sender: TObject;
var
Key: Char);
443
var
444
CodeIdx: integer;
445
ObjName:
string
;
446
begin
447
if
Key
=
Char(
13
)
then
begin
448
ObjName:
=
(Sender
as
TRzEdit).Name;
449
CodeIdx:
=
StrToInt(Copy(ObjName,
6
,
1
));
450
CodingOK(CodeIdx);
451
if
CodeIdx
=
9
then
452
CodeIdx:
=
1
453
else
454
CodeIdx:
=
CodeIdx
+
1
;
455
TRzEdit(FindComponent(
'
Input
'
+
IntToStr(CodeIdx))).SetFocus;
456
end
;
457
end
;
458
459
end
.