最近在做一个公众号, 通过公众号可以查询联盟优惠券的功能. 由于查券服务器很多api需要联盟的cookie, 这就需要这个登录状态保持.
开始觉得应该定时刷新一个联盟API就好了, 事实是不行.
那就自己做自动登录吧, 这个好像挺复杂的, 懒.(因为有各种验证码, js点击), 还有一点就是我使用了另外的方法.
是什么方法呢? 就是用现成的登录程序.
举个例子, 大淘客都知道吧, 大淘客的登录程序做的不错, 拿来用就是了.

这个都熟悉吧, 不熟悉就拿一个你觉得熟悉的登录程序吧, 大同小异.
等等, 你说这个AliLogin.exe怎么双击启动不了啊, 好像是啊, 那大淘客怎么启动的呢?
哈哈, 那就是命令参数了, 怎么看命令参数呢,
百度里搜索: 如何获得软件的启动参数
然后得到结果: 1、先启动程序2、在开始–>运行–>输入 cmd 回车 进入命令行3、输入:WMIC 出来提示后 输入: process 就会显示所有的进程命令行信息了
用这个方法, 我们就得到了命令启动参数: -lt 1 -ac -ap -dc -dp -pn AL6362845535841316741047753041
不懂什么意思, 能用就行
好了, 试试吧, 看灵不灵
sCmd := '-lt 1 -ac -ap -dc -dp -pn AL6362845535841316741047753041'; sPath := ExtractFilePath(ParamStr(0)); ShellExecute(0, 'open', PChar(sPath+'AliLogin.exe'), PChar(sCmd), nil, SW_SHOWNORMAL);
运行起来了. 然后呢, 运行起来也不行啊, 虽然登录联盟成功了, 但是cookie怎么得到呢, 对哦, 答案是我们用注入.
HOOK代码如下:

unit APIHook;
interface
uses
SysUtils,Dialogs,Windows, WinSock, Classes;
type
//要HOOK的API函数定义
TSockProc = function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
PJmpCode = ^TJmpCode;
TJmpCode = packed record
JmpCode: BYTE;
Address: TSockProc;
MovEAX: array[0..2] of BYTE;
end;
//--------------------函数声明---------------------------
procedure HookAPI;
procedure UnHookAPI;
var
FLoad: TStringList;
function recvout(var Rbuf; RLen: Integer): Integer;
var
OldSend, OldRecv: TSockProc; //原来的API地址
JmpCode: TJmpCode;
OldProc: array[0..1] of TJmpCode;
AddSend, AddRecv: pointer; //API地址
TmpJmp: TJmpCode;
ProcessHandle: THandle;
gLastTime: THandle;
gCookie: string;
gOldCook: string='';
implementation
function GetStrEx(sSrc, sStart, sEnd: string): string;
var
nPos1, nPos2: Integer;
sStr: string;
begin
Result := '';
nPos1 := Pos(sStart, sSrc);
if nPos1 = 0 then Exit;
sStr := Copy(sSrc, nPos1+length(sStart), Length(sSrc)-nPos1);
nPos1 := Pos(sEnd, sStr);
if nPos1>0 then
Result := Copy(sStr, 1, nPos1-1)
else
Result := sStr;
end;
function recvout(var Rbuf; RLen: Integer): Integer;
var
buf1: pchar;
i: integer;
ss: string;
begin
// OutputDebugString(PChar('************:'));
buf1 := @Rbuf;
ss := buf1;
//OutputDebugString(PChar('当前:'+ss));
//取cookie
gCookie := GetStrEx(ss, 'Cookie:', 'Host:');
if Pos('t=', gCookie)>0 then
begin
if GetTickCount-gLastTime > 30*1000 then
begin
gLastTime := GetTickCount;
OutputDebugString(PChar('Cookie:'+gCookie));
if gCookie <> gOldCook then
begin
gOldCook := gCookie;
OutputDebugString(PChar('保存Cookie文件:'+ExtractFilePath(ParamStr(0))+'cook.txt'));
FLoad.Clear;
FLoad.Add(gCookie);
FLoad.SaveToFile(ExtractFilePath(ParamStr(0))+'cook.txt');
end;
end;
end;
end;
{---------------------------------------}
{函数功能:Send函数的HOOK
{函数参数:同Send
{函数返回值:integer
{---------------------------------------}
function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
//这儿进行发送的数据处理
// MessageBeep(1000); //简单的响一声
recvout(Buf, len);
//调用直正的Send函数
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
Result := OldSend(S, Buf, len, flags);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
end;
{---------------------------------------}
{函数功能:Recv函数的HOOK
{函数参数:同Recv
{函数返回值:integer
{---------------------------------------}
function MyRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
//这儿进行接收的数据处理
// MessageBeep(1000); //简单的响一声
//调用直正的Recv函数
WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
Result := OldRecv(S, Buf, len, flags);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);
end;
{------------------------------------}
{过程功能:HookAPI
{过程参数:无
{------------------------------------}
procedure HookAPI;
var
DLLModule: THandle;
dwSize: cardinal;
begin
ProcessHandle := GetCurrentProcess;
DLLModule := LoadLibrary('ws2_32.dll');
AddSend := GetProcAddress(DLLModule, 'send'); //取得API地址
// AddRecv := GetProcAddress(DLLModule, 'recv');
JmpCode.JmpCode := $B8;
JmpCode.MovEAX[0] := $FF;
JmpCode.MovEAX[1] := $E0;
JmpCode.MovEAX[2] := 0;
ReadProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); //修改Send入口
// ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
//JmpCode.Address := @MyRecv;
// WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); //修改Recv入口
OldSend := AddSend;
// OldRecv := AddRecv;
FLoad := TStringList.Create();
gLastTime := 0;
end;
{------------------------------------}
{过程功能:取消HOOKAPI
{过程参数:无
{------------------------------------}
procedure UnHookAPI;
var
dwSize: Cardinal;
begin
if FLoad <> nil then
FLoad.Free;
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
// WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
end;
end.
原理就是用钩子注入AliLogin.exe进程, 捕获这个进程所有的发送数据包, 从中间查找cookie, 然后保存下来.
至此cookie问题解决.

明天我们来解决一下多个程序cookie共享的问题.
程序下载 请加技术群下载
来源:https://www.cnblogs.com/doorsky/p/6749723.html
