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

Delphi 也玩 LPK !

本帖最后由 莱莉 于 2010-4-16 09:31 编辑

【文章标题】: Delphi 也玩 LPK !
【文章作者】: 莱莉
【使用工具】: D-Delphi
【操作平台】: D-Windows XP3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
  【解说前闲谈】
--------------------------------------------------------------------------------
  近日来易语言版LPK在论坛上打的相当的凶啊!黑月LPK在论坛上无处不在,这样搞到其它

语言好像没有发为的余地。其实易语言的LPK会那么疯狂传播,全赖于黑月插件。这个插件也

真的是相当的强大,它大大的减小了易语言的体积,还做出了超强大的LPK模块。这里我也只

能膜拜作者的强大,但这并不代表我赞同易语言是种强大的语言。他之所以强大是在C语言的

基础上而延伸来的。易语言要做的越是智能化,背后的开发者就要写越多代码。我们用黑月的

LPK 模块时看上去都算麻烦了要贴出那么多代码,但你可曾想过作者又写了多少代码啊!我敢说

不会少于一百行,再说易是在C的基础上开发而来的。这就好比你用手就能装点水来喝,可现在

却要去拿个勺子再装来喝。你说这样能高效的哪里去,还有那黑月LPK毕竟要有那个插件才能得以实现

如何哪天黑月要收费了。那么今日的风光就如昨日黄花,稍纵即逝!要说真正编程三大语言

才是的黄道。今天我就来丢下人了,用Delphi来LPK一番!

--------------------------------------------------------------------------------
【Lpk原理解说】

--------------------------------------------------------------------------------
  看过《神奇的马甲》的人都知道,Lpk 就是在DLL劫持技术所派生出来的!在早期微软开发时

为了减少对系统文件的使量,一些非常支持应用程序文件都放在同一目录下,所以系统会强制

加载根目录下的系统文件,当找不到时才去动系统文件。这样我们就可以抓住这个特征,伪造

一个系统文件,但是输出函数却交还给系统文件来完成。我们只要劫持一些有用的函数就好了。

--------------------------------------------------------------------------------
【Lpk的实现】

--------------------------------------------------------------------------------
  因为我也是个菜鸟不太懂那个劫持功能要如何实现,所以在论坛上找了个框架:
--------------------------------------------------------------------------------
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 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.
--------------------------------------------------------------------------------
好了有了这个强大的框架之后我们就来patch了,其实patch这东西就是用死writeProcessMemory

这个API罢了。不过在用之我们要先找到我们要操作的句柄,有了句柄就再打开它写入。说个容

形点的比喻吧!patch就好比我们把钱放到保险箱里面一样,你要先找到你的保险箱,然后再打开

他,最后把钱放在那一格。你那么有钱,有的格是装十块,二十的,有的是装五十,一百。还有

装千万的,不过我们国家好像还没有千的面额啊!不管了我们先来存钱再说:
--------------------------------------------------------------------------------
在找保险箱前,要拿点工具先!在1,定个全局,2处定义一些局部变量就好了:
--------------------------------------------------------------------------------
   test:array   of   byte;   //读取时用的字节集,点数时用了你不怕少钱了(不全局会改变)

   pid  :HWND ;  //DLL句柄,就是保险箱地图了
   pHandle:HWND; //打开句柄后的标认,密码
   zjj:array  of byte ;  //要修改的内容,放装出的钱
   buf:array   of   char; //显示时用的字节集,打张清单
   lpNumberOfBytesRead:DWORD; //Api 参数,相当于摆设了不过不能没啊!
--------------------------------------------------------------------------------
  做好了准备就来存钱了,在3处写入实现代码:
--------------------------------------------------------------------------------
   zjj :=116 ;  //字节赋值,
   zjj :=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);         //关闭线程 ,点完就要关门了
--------------------------------------------------------------------------------
  存了钱也要点点数啊!在4外返谴一些相关信息:
--------------------------------------------------------------------------------
   wvsprintf(buf, '%c', pchar(@test)); //格式化字符,写成大写怕被人改啊!
   MessageBox(0,buf,'',0); //输出BOX信息,终于列出清单来了看看有没有少钱不;
【经验总结】
--------------------------------------------------------------------------------
1.这个框架消息框的API不太好使有,尤其在3处要是写入BOX的API就会出错。我也不知道为什么。

2.在最后格式化输出又不能输出数值,并且还非全局变量不可。可能使用好有某些因素使它改变了。

3.整个DLL都是用纯API来实现的,VCL函数是无法实现的。你可自己试加加看,我太菜了不会加。
--------------------------------------------------------------------------------

【版权声明】: 本文原创于UpK论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                      2010年04月15日 22:38:38

   

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

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

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

楼主很强悍呐。

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

回复 3# ycs


    呵呵!打错了!

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

呵呵,用在外挂上正好

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

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

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

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

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

很详细,学习了.

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

本帖最后由 十万个为什么 于 2010-4-16 04:53 编辑

哇...
好...

我要anti这玩意的话。

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



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

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

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

收藏....学习。。

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

本帖最后由 BeyondMe 于 2010-4-16 07:37 编辑

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

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

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

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

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

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

黑胡子来了

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

回复 11# BeyondMe


    我用DELPHI和你比起来还错多了,要我是牛X那你就是牛XXXXXXXX!:funk:
页: [1] 2 3 4 5
查看完整版本: Delphi 也玩 LPK !