UpK软件安全社区's Archiver

莱莉 发表于 2010-4-15 22:47

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]

7908860 发表于 2010-4-15 23:05

黑月永久免费 永不收费。。作者说的。。

ycs 发表于 2010-4-15 23:15

楼主很强悍呐。
[attach]34253[/attach]

莱莉 发表于 2010-4-15 23:20

[b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=651295&ptid=48261]3#[/url] [i]ycs[/i] [/b]


    呵呵!打错了!

天下无雪 发表于 2010-4-15 23:54

呵呵,用在外挂上正好

夜凉如水 发表于 2010-4-16 00:14

delphi的lpk 好像playboysen 以前写过一个生成器了 呵呵

Sam.com 发表于 2010-4-16 02:34

多学些东西没坏处~~~~谢谢了

jk888 发表于 2010-4-16 04:08

很详细,学习了.

十万个为什么 发表于 2010-4-16 04:51

[i=s] 本帖最后由 十万个为什么 于 2010-4-16 04:53 编辑 [/i]

哇...
好...

我要anti这玩意的话。

我就对fs赋予假值,,,给
GetCurrentProcessId ()
做个陷阱.........................



我系统是精简xp。。。一直米用上lpk.dll

难到不需要语言包?......

vistann 发表于 2010-4-16 07:27

收藏....学习。。

BeyondMe 发表于 2010-4-16 07:34

[i=s] 本帖最后由 BeyondMe 于 2010-4-16 07:37 编辑 [/i]

讲解很详细,代码很强大,作者很牛X!

onlylovewww 发表于 2010-4-16 08:15

此贴很强大   解释很详细清楚。

ddiiccoo 发表于 2010-4-16 08:31

写的非常好,谢谢分享了!

starfall 发表于 2010-4-16 08:41

黑胡子来了

莱莉 发表于 2010-4-16 09:23

[b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=651609&ptid=48261]11#[/url] [i]BeyondMe[/i] [/b]


    我用DELPHI和你比起来还错多了,要我是牛X那你就是牛XXXXXXXX!:funk:

莱莉 发表于 2010-4-16 09:34

[i=s] 本帖最后由 莱莉 于 2010-4-16 09:35 编辑 [/i]

晕!在3处实现代码出了个BUG,少了句 CloseHandle(phandle);         //关闭线程 ,点完就要关门了
难怪我会那么穷,都不关门再有钱都会被人偷光啊!:dizzy:现在文章和附件都修复了!可不安心下载。

hxsoft 发表于 2010-4-16 09:48

写得非常不错,学习了!

flyboyfeng 发表于 2010-4-16 10:36

解释很详细清楚,菜鸟应该也能了解一二了。{:3_86:}

BeyondMe 发表于 2010-4-16 14:46

你太谦虚了。
这个话题貌似很有趣,还有关于lpk的其它Delphi源码吗?

1905 发表于 2010-4-16 15:10

今天就收藏这个帖了{:2_67:}
回去研究下。

莱莉 发表于 2010-4-16 16:25

[b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=652120&ptid=48261]19#[/url] [i]BeyondMe[/i] [/b]


    我也想有啊!牛人都是用C的,现在我手上有海风神奇的马甲DLL源码。还有看雪,以及易的。几份一超看的我头都晕死了,就是没多些DELPHI的!:dizzy:

snailxp 发表于 2010-4-17 12:57

LZ是个打字速度和错别字数量成正比的人。

c740073529 发表于 2010-4-17 13:27

:D:只看懂一部分代码

fdsajhg1000 发表于 2010-4-17 16:18

说话难听的话..

delphin..的路已经很难走了.   
敢问 到windows7哪代.   
delphin应当如何应付.    代码库的陈旧.

黑夜彩虹 发表于 2010-4-17 18:29

phandle := OpenProcess([color=Red]2035711[/color],False,pid); //这是打开保险箱的密码

弱弱的问一下:2035711 这个值是从哪里得到的?


writeProcessMemory(pHandle,Pointer([color=RoyalBlue]4198615[/color]),@zjj,2,lpNumberOfBytesRead);//存钱

4198615 这个是16进制的地址...

莱莉 发表于 2010-4-17 22:37

[b]回复 [url=http://www.unpack.cn/redirect.php?goto=findpost&pid=653317&ptid=48261]25#[/url] [i]黑夜彩虹[/i] [/b]


    偶像的问题当然要答了!2字开头的是宏的代号数你百一下OPE这个函数就有不,你可用宏也可用代码.还有4那个是内存地址!

hj2008mt 发表于 2010-4-18 02:20

看不懂,来支持的

xiaocainiaok 发表于 2010-4-18 09:54

膜拜下 先..

xie83544109 发表于 2010-4-18 10:50

{:3_100:}
哦永远都会记得你们这些无私的大牛,对哦们这些小鸟地好处
多谢你们。。!

freecat 发表于 2010-4-18 13:35

delphi lpk已被ms和谐了 win2k3 sp2... win7... win2k8

页: [1] 2

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.