最近在做一个公众号, 通过公众号可以查询联盟优惠券的功能. 由于查券服务器很多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共享的问题.
程序下载 请加技术群下载