飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3502|回复: 4

delphi编写的外挂型DLL有问题,求助!

[复制链接]

该用户从未签到

发表于 2007-8-20 10:01:06 | 显示全部楼层 |阅读模式
下面是需要破解的程序,它每次调用LPK.dll
我就写个DLL来做内存补丁.

原理:把自己写的DLL放程序目录,程序就会先调用它,有人用C语言写成功过.

crackme.rar (3.42 KB, 下载次数: 12)
lpk.rar (1.46 KB, 下载次数: 12)

我写了个DLL用来动态修改内存的,模拟WINDOWS的LPK.dll
但静态调用时出错!谁帮我看下!

  1. library lpk;

  2. { Important note about DLL memory management: ShareMem must be the
  3.   first unit in your library's USES clause AND your project's (select
  4.   Project-View Source) USES clause if your DLL exports any procedures or
  5.   functions that pass strings as parameters or function results. This
  6.   applies to all strings passed to and from your DLL--even those that
  7.   are nested in records and classes. ShareMem is the interface unit to
  8.   the BORLNDMM.DLL shared memory manager, which must be deployed along
  9.   with your DLL. To avoid using BORLNDMM.DLL, pass string information
  10.   using PChar or ShortString parameters. }


  11. uses
  12.   SysUtils,
  13.   windows,
  14.   Classes;


  15. var
  16.   wj1,wj2,wj3,wj4,wj5,wj6,wj7,wj8,wj9,wj10,wj11:pointer;
  17. {$R *.res}
  18. procedure DLLEntry(reason: DWORD); //dll装载时执行
  19. var
  20.   ljj:PChar;
  21.   ljj2:string;
  22.   DLLHandle: THandle;
  23.   pData:pointer;
  24.   mbi_thunk: TMemoryBasicInformation;
  25. begin
  26.   case reason of
  27.     DLL_PROCESS_ATTACH:
  28.     begin
  29.     ljj:=AllocMem(512);
  30.     GetSystemDirectory(ljj,256);              //获取系统目录
  31.     ljj2:=string(ljj)+'\lpk.dll' ;      //连接"\lpk.dll"
  32.     ljj:=nil;
  33.     FreeMem(ljj);
  34.     DLLHandle := LoadLibrary(PChar(ljj2));
  35. //下面是获取LPK.DLL的输出函数
  36.     wj1:=GetProcAddress(DLLHandle, 'ftsWordBreak');
  37.     wj2:=GetProcAddress(DLLHandle, 'LpkUseGDIWidthCache');
  38.     wj3:=GetProcAddress(DLLHandle, 'LpkPSMTextOut');
  39.     wj4:=GetProcAddress(DLLHandle, 'LpkGetTextExtentExPoint');
  40.     wj5:=GetProcAddress(DLLHandle, 'LpkGetCharacterPlacement');
  41.     wj6:=GetProcAddress(DLLHandle, 'LpkExtTextOut');
  42.     wj7:=GetProcAddress(DLLHandle, 'LpkEditControl');
  43.     wj8:=GetProcAddress(DLLHandle, 'LpkDrawTextEx');
  44.     wj9:=GetProcAddress(DLLHandle, 'LpkDllInitialize');
  45.     wj10:=GetProcAddress(DLLHandle, 'LpkTabbedTextOut');
  46.     wj11:=GetProcAddress(DLLHandle, 'LpkInitialize');
  47.    //下面是修改内存程序段 ,(这段去掉也不能加载,不是下面这段的问题)
  48.     pData := pointer($00403296);
  49.    //查询页信息。
  50.    VirtualQuery(pData, mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
  51.    / /改变页保护属性为读写。
  52.     asm
  53.     push eax
  54.     push edx
  55.     mov eax,$4024E0
  56.     cmp [eax],$358b6674
  57.     jne @@11
  58.     mov edx,$358b9090
  59.     mov [eax],edx
  60.     @@11:
  61.     pop edx
  62.     pop eax
  63.     end;

  64.     end;
  65.     DLL_PROCESS_DETACH:
  66.     begin

  67.     end;
  68.   end;
  69. end;




  70. procedure ftsWordBreak;stdcall; //模拟windows的lpk.dll的函数
  71. begin
  72. asm
  73. jmp wj1
  74. end;
  75. end;

  76. procedure LpkUseGDIWidthCache;stdcall; //模拟windows的lpk.dll的函数
  77. begin
  78. asm
  79. jmp wj2
  80. end;
  81. end;

  82. procedure LpkPSMTextOut;stdcall; //模拟windows的lpk.dll的函数
  83. begin
  84. asm
  85. jmp wj3
  86. end;
  87. end;

  88. procedure LpkGetTextExtentExPoint;stdcall; //模拟windows的lpk.dll的函数
  89. begin
  90. asm
  91. jmp wj4
  92. end;
  93. end;

  94. procedure LpkGetCharacterPlacement;stdcall; //模拟windows的lpk.dll的函数
  95. begin
  96. asm
  97. jmp wj5
  98. end;
  99. end;

  100. procedure LpkExtTextOut;stdcall; //模拟windows的lpk.dll的函数
  101. begin
  102. asm
  103. jmp wj6
  104. end;
  105. end;


  106. procedure LpkEditControl;stdcall; //模拟windows的lpk.dll的函数
  107. begin
  108. asm
  109. jmp wj7
  110. end;
  111. end;


  112. procedure LpkDrawTextEx;stdcall; //模拟windows的lpk.dll的函数
  113. begin
  114. asm
  115. jmp wj8
  116. end;
  117. end;

  118. procedure LpkDllInitialize;stdcall; //模拟windows的lpk.dll的函数
  119. begin
  120. asm
  121. jmp wj9
  122. end;
  123. end;

  124. procedure LpkTabbedTextOut;stdcall; //模拟windows的lpk.dll的函数
  125. begin
  126. asm
  127. jmp wj10
  128. end;
  129. end;

  130. procedure LpkInitialize;stdcall;  //模拟windows的lpk.dll的函数
  131. begin
  132. asm
  133. jmp wj11
  134. end;
  135. end;


  136. exports
  137.   ftsWordBreak Index 11,
  138.   LpkUseGDIWidthCache Index 10,
  139.   LpkPSMTextOut Index 9,
  140.   LpkGetTextExtentExPoint Index 8,
  141.   LpkGetCharacterPlacement Index 7,
  142.   LpkExtTextOut Index 6,
  143.   LpkEditControl Index 5,
  144.   LpkDrawTextEx Index 4,
  145.   LpkDllInitialize Index 3,
  146.   LpkTabbedTextOut Index 2,
  147.   LpkInitialize Index 1;

  148. begin
  149.   DLLProc := @DLLEntry;
  150.   DLLEntry(DLL_PROCESS_ATTACH);
  151. end.
复制代码

先谢谢了!

[ 本帖最后由 johnroot 于 2007-8-20 12:16 编辑 ]
PYG19周年生日快乐!

该用户从未签到

发表于 2007-8-20 10:11:23 | 显示全部楼层
标记,回头学习。。。。/:good
PYG19周年生日快乐!

该用户从未签到

发表于 2007-8-20 20:31:02 | 显示全部楼层

  1.     wj1:=GetProcAddress(DLLHandle, 'ftsWordBreak');
  2.     wj2:=GetProcAddress(DLLHandle, 'LpkUseGDIWidthCache');
  3.     wj3:=GetProcAddress(DLLHandle, 'LpkPSMTextOut');
  4.     wj4:=GetProcAddress(DLLHandle, 'LpkGetTextExtentExPoint');
  5.     wj5:=GetProcAddress(DLLHandle, 'LpkGetCharacterPlacement');
  6.     wj6:=GetProcAddress(DLLHandle, 'LpkExtTextOut');
  7.     wj7:=GetProcAddress(DLLHandle, 'LpkEditControl');
  8.     wj8:=GetProcAddress(DLLHandle, 'LpkDrawTextEx');
  9.     wj9:=GetProcAddress(DLLHandle, 'LpkDllInitialize');
  10.     wj10:=GetProcAddress(DLLHandle, 'LpkTabbedTextOut');
  11.     wj11:=GetProcAddress(DLLHandle, 'LpkInitialize');
复制代码


这种调用应该要有函数原型的吧.Delphi应该也有函数指针的.


  1. procedure LpkExtTextOut;stdcall; //模拟windows的lpk.dll的函数
  2. begin
  3. asm
  4. jmp wj6
  5. end;
  6. end;
复制代码

   这种就跳到DLL执行,参数无法传递了..

[ 本帖最后由 Gue 于 2007-8-20 20:33 编辑 ]
PYG19周年生日快乐!

该用户从未签到

发表于 2007-8-21 09:20:50 | 显示全部楼层
有没有C语言版本的参考下?
PYG19周年生日快乐!

该用户从未签到

发表于 2007-8-21 15:39:38 | 显示全部楼层
我的机器有人在用着,这些是在记事本里写的,没有测试过...

以MessageBox为例, 在MSDN上查得原型如下:

  1. int MessageBox(          HWND hWnd,
  2.     LPCTSTR lpText,
  3.     LPCTSTR lpCaption,
  4.     UINT uType
  5. );
复制代码


因此,我们定义函数原型

  1. typedef int (WINAPI *MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, UINT);

  2. //定义指向这一类函数的指针

  3. MESSAGEBOX _MessageBox;

  4. //加载User32.dll
  5. HANDLE hUser32 = LoadLibrary("User32.dll");

  6. if (hUser32) {
  7.         //获取MessageBoxA的地址
  8.         _MessageBox = (MESSAGEBOX)GetProcAddress(hUser32, "MessageBoxA");
  9. }


  10. int WINAPI MessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
  11. {
  12.         //在这里做你想做的事
  13.        
  14.         return _MessageBox(hWnd, lpText, lpCaption, uType);
  15. }


  16. //卸载本DLL前卸载掉User32.dll
复制代码
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表