Delphi 也玩 LPK !
[i=s] 本帖最后由 莱莉 于 2010-4-16 09:31 编辑 [/i]【文章标题】: Delphi 也玩 LPK !
【文章作者】: 莱莉
【使用工具】: D-Delphi
【操作平台】: D-Windows XP3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【解说前闲谈】
--------------------------------------------------------------------------------
近日来易语言版LPK在论坛上打的相当的凶啊!黑月LPK在论坛上无处不在,这样搞到其它
语言好像没有发为的余地。其实易语言的LPK会那么疯狂传播,全赖于黑月插件。这个插件也
真的是相当的强大,它大大的减小了易语言的体积,还做出了超强大的LPK模块。这里我也只
能膜拜作者的强大,但这并不代表我赞同易语言是种强大的语言。他之所以强大是在C语言的
基础上而延伸来的。易语言要做的越是智能化,背后的开发者就要写越多代码。我们用黑月的
LPK 模块时看上去都算麻烦了要贴出那么多代码,但你可曾想过作者又写了多少代码啊!我敢说
不会少于一百行,再说易是在C的基础上开发而来的。这就好比你用手就能装点水来喝,可现在
却要去拿个勺子再装来喝。你说这样能高效的哪里去,还有那黑月LPK毕竟要有那个插件才能得以实现
如何哪天黑月要收费了。那么今日的风光就如昨日黄花,稍纵即逝!要说真正编程三大语言
才是的黄道。今天我就来丢下人了,用Delphi来LPK一番!
--------------------------------------------------------------------------------
【Lpk原理解说】
--------------------------------------------------------------------------------
看过《神奇的马甲》的人都知道,Lpk 就是在DLL劫持技术所派生出来的!在早期微软开发时
为了减少对系统文件的使量,一些非常支持应用程序文件都放在同一目录下,所以系统会强制
加载根目录下的系统文件,当找不到时才去动系统文件。这样我们就可以抓住这个特征,伪造
一个系统文件,但是输出函数却交还给系统文件来完成。我们只要劫持一些有用的函数就好了。
--------------------------------------------------------------------------------
【Lpk的实现】
--------------------------------------------------------------------------------
因为我也是个菜鸟不太懂那个劫持功能要如何实现,所以在论坛上找了个框架:
--------------------------------------------------------------------------------[code]
Library lpk;
uses
Windows;
var
/////////////////////////////////////////
// 1.这里可定义一些全局变量
/////////////////////////////////////////
ModHandle: Cardinal = 0;
POldLpkDllInitialize,
POldLpkDrawTextEx,
POldLpkExtTextOut,
POldLpkGetCharacterPlacement,
POldLpkGetTextExtentExPoint,
POldLpkPSMTextOut,
POldLpkUseGDIWidthCache,
POldftsWordBreak,
POldLpkInitialize,
POldLpkTabbedTextOut,
POldLpkEditControl: Pointer;
Procedure LpkDllInitialize; Stdcall;
Asm jmp POldLpkDllInitialize
End;
Procedure LpkDrawTextEx; Stdcall;
Asm jmp POldLpkDrawTextEx
End;
Procedure LpkExtTextOut; Stdcall;
Asm jmp POldLpkExtTextOut
End;
Procedure LpkGetCharacterPlacement; Stdcall;
Asm jmp POldLpkGetCharacterPlacement
End;
Procedure LpkGetTextExtentExPoint; Stdcall;
Asm jmp POldLpkGetTextExtentExPoint
End;
Procedure LpkPSMTextOut; Stdcall;
Asm jmp POldLpkPSMTextOut
End;
Procedure LpkUseGDIWidthCache; Stdcall;
Asm jmp POldLpkUseGDIWidthCache
End;
Procedure ftsWordBreak; Stdcall;
Asm jmp POldftsWordBreak
End;
Procedure LpkInitialize; Stdcall;
Asm jmp POldLpkInitialize
End;
Procedure LpkTabbedTextOut; Stdcall;
Asm jmp POldLpkTabbedTextOut
End;
Procedure LpkEditControl; Stdcall;
Asm
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
End;
Procedure ModMemData();
Var
dwOldProtect: DWORD;
Begin
VirtualProtect(@LpkEditControl, $40, PAGE_READWRITE, @dwOldProtect);
End;
Procedure lpk_DllHandler(Reason: Integer);
Var
/////////////////////////////////////////
// 2.这里可定义一些局部变量
/////////////////////////////////////////
SysDir: Array[0..256] Of Char;
LibPath: String;
Begin
Case Reason Of
DLL_PROCESS_ATTACH:
Begin
GetSystemDirectory(SysDir, 256);
LibPath := SysDir + '\LPK.DLL';
ModHandle := LoadLibrary(PChar(LibPath));
If ModHandle > 0 Then
Begin
ModMemData;
POldLpkDllInitialize := GetProcAddress(ModHandle, 'LpkDllInitialize');
POldLpkDrawTextEx := GetProcAddress(ModHandle, 'LpkDrawTextEx');
POldLpkExtTextOut := GetProcAddress(ModHandle, 'LpkExtTextOut');
POldLpkGetCharacterPlacement := GetProcAddress(ModHandle,
'LpkGetCharacterPlacement');
POldLpkGetTextExtentExPoint := GetProcAddress(ModHandle,
'LpkGetTextExtentExPoint');
POldLpkPSMTextOut := GetProcAddress(ModHandle, 'LpkPSMTextOut');
POldLpkUseGDIWidthCache := GetProcAddress(ModHandle, 'LpkUseGDIWidthCache');
POldftsWordBreak := GetProcAddress(ModHandle, 'ftsWordBreak');
POldLpkInitialize := GetProcAddress(ModHandle, 'LpkInitialize');
POldLpkTabbedTextOut := GetProcAddress(ModHandle, 'LpkTabbedTextOut');
POldLpkEditControl := GetProcAddress(ModHandle, 'LpkEditControl');
Asm
pushad
mov esi, eax
lea edi, LpkEditControl
mov ecx, 40h
rep movsb
popad
End;
/////////////////////////////////////////
// 3.这里是我们的LPK实现部分
/////////////////////////////////////////
End Else ExitProcess(0);
End;
DLL_PROCESS_DETACH:
Begin
/////////////////////////////////////////
//4. 这里是整程结束后的后期实现
/////////////////////////////////////////
If ModHandle <> 0 Then FreeLibrary(ModHandle);
End;
DLL_THREAD_ATTACH: ;
DLL_THREAD_DETACH: ;
End;
End;
Exports
LpkDllInitialize,
LpkDrawTextEx,
LpkEditControl,
LpkExtTextOut,
LpkGetCharacterPlacement,
LpkGetTextExtentExPoint,
LpkPSMTextOut,
LpkUseGDIWidthCache,
ftsWordBreak,
LpkInitialize,
LpkTabbedTextOut;
Begin
DLLProc := @lpk_DllHandler;
DLLProc(DLL_PROCESS_ATTACH);
End.
[/code]--------------------------------------------------------------------------------
好了有了这个强大的框架之后我们就来patch了,其实patch这东西就是用死writeProcessMemory
这个API罢了。不过在用之我们要先找到我们要操作的句柄,有了句柄就再打开它写入。说个容
形点的比喻吧!patch就好比我们把钱放到保险箱里面一样,你要先找到你的保险箱,然后再打开
他,最后把钱放在那一格。你那么有钱,有的格是装十块,二十的,有的是装五十,一百。还有
装千万的,不过我们国家好像还没有千的面额啊!不管了我们先来存钱再说:
--------------------------------------------------------------------------------
在找保险箱前,要拿点工具先!在1,定个全局,2处定义一些局部变量就好了:
--------------------------------------------------------------------------------[code]
test:array[0..1] of byte; //读取时用的字节集,点数时用了你不怕少钱了(不全局会改变)
[/code][code]
pid :HWND ; //DLL句柄,就是保险箱地图了
pHandle:HWND; //打开句柄后的标认,密码
zjj:array[0..1] of byte ; //要修改的内容,放装出的钱
buf:array[0..1] of char; //显示时用的字节集,打张清单
lpNumberOfBytesRead:DWORD; //Api 参数,相当于摆设了不过不能没啊!
[/code]--------------------------------------------------------------------------------
做好了准备就来存钱了,在3处写入实现代码:
--------------------------------------------------------------------------------[code]
zjj[0] :=116 ; //字节赋值,
zjj[1] :=22; //看要存多钱了
pid := GetCurrentProcessId (); //找到保险箱
phandle := OpenProcess(2035711,False,pid); //这是打开保险箱的密码
writeProcessMemory(pHandle,Pointer(4198615),@zjj,2,lpNumberOfBytesRead);//存钱
ReadProcessMemory(pHandle,Pointer(4198615),@test,sizeof(test),lpNumberOfBytesRead);//点钱
CloseHandle(phandle); //关闭线程 ,点完就要关门了
[/code]--------------------------------------------------------------------------------
存了钱也要点点数啊!在4外返谴一些相关信息:
--------------------------------------------------------------------------------[code]
wvsprintf(buf, '%c', pchar(@test)); //格式化字符,写成大写怕被人改啊!
MessageBox(0,buf,'',0); //输出BOX信息,终于列出清单来了看看有没有少钱不;
[/code]【经验总结】
--------------------------------------------------------------------------------
1.这个框架消息框的API不太好使有,尤其在3处要是写入BOX的API就会出错。我也不知道为什么。
2.在最后格式化输出又不能输出数值,并且还非全局变量不可。可能使用好有某些因素使它改变了。
3.整个DLL都是用纯API来实现的,VCL函数是无法实现的。你可自己试加加看,我太菜了不会加。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于UpK论坛, 转载请注明作者并保持文章的完整, 谢谢!
2010年04月15日 22:38:38
[attach]34252[/attach]
[attach]34251[/attach] 黑月永久免费 永不收费。。作者说的。。 楼主很强悍呐。
[attach]34253[/attach] [b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=651295&ptid=48261]3#[/url] [i]ycs[/i] [/b]
呵呵!打错了! 呵呵,用在外挂上正好 delphi的lpk 好像playboysen 以前写过一个生成器了 呵呵 多学些东西没坏处~~~~谢谢了 很详细,学习了. [i=s] 本帖最后由 十万个为什么 于 2010-4-16 04:53 编辑 [/i]
哇...
好...
我要anti这玩意的话。
我就对fs赋予假值,,,给
GetCurrentProcessId ()
做个陷阱.........................
哈
我系统是精简xp。。。一直米用上lpk.dll
难到不需要语言包?...... 收藏....学习。。 [i=s] 本帖最后由 BeyondMe 于 2010-4-16 07:37 编辑 [/i]
讲解很详细,代码很强大,作者很牛X! 此贴很强大 解释很详细清楚。 写的非常好,谢谢分享了! 黑胡子来了 [b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=651609&ptid=48261]11#[/url] [i]BeyondMe[/i] [/b]
我用DELPHI和你比起来还错多了,要我是牛X那你就是牛XXXXXXXX!:funk: [i=s] 本帖最后由 莱莉 于 2010-4-16 09:35 编辑 [/i]
晕!在3处实现代码出了个BUG,少了句 CloseHandle(phandle); //关闭线程 ,点完就要关门了
难怪我会那么穷,都不关门再有钱都会被人偷光啊!:dizzy:现在文章和附件都修复了!可不安心下载。 写得非常不错,学习了! 解释很详细清楚,菜鸟应该也能了解一二了。{:3_86:} 你太谦虚了。
这个话题貌似很有趣,还有关于lpk的其它Delphi源码吗? 今天就收藏这个帖了{:2_67:}
回去研究下。 [b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=652120&ptid=48261]19#[/url] [i]BeyondMe[/i] [/b]
我也想有啊!牛人都是用C的,现在我手上有海风神奇的马甲DLL源码。还有看雪,以及易的。几份一超看的我头都晕死了,就是没多些DELPHI的!:dizzy: LZ是个打字速度和错别字数量成正比的人。 :D:只看懂一部分代码 说话难听的话..
delphin..的路已经很难走了.
敢问 到windows7哪代.
delphin应当如何应付. 代码库的陈旧. phandle := OpenProcess([color=Red]2035711[/color],False,pid); //这是打开保险箱的密码
弱弱的问一下:2035711 这个值是从哪里得到的?
writeProcessMemory(pHandle,Pointer([color=RoyalBlue]4198615[/color]),@zjj,2,lpNumberOfBytesRead);//存钱
4198615 这个是16进制的地址... [b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=653317&ptid=48261]25#[/url] [i]黑夜彩虹[/i] [/b]
偶像的问题当然要答了!2字开头的是宏的代号数你百一下OPE这个函数就有不,你可用宏也可用代码.还有4那个是内存地址! 看不懂,来支持的 膜拜下 先.. {:3_100:}
哦永远都会记得你们这些无私的大牛,对哦们这些小鸟地好处
多谢你们。。! delphi lpk已被ms和谐了 win2k3 sp2... win7... win2k8
页:
[1]
2