johnroot 发表于 2007-8-20 10:01:06

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

下面是需要破解的程序,它每次调用LPK.dll
我就写个DLL来做内存补丁.

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




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

library lpk;

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


uses
SysUtils,
windows,
Classes;


var
wj1,wj2,wj3,wj4,wj5,wj6,wj7,wj8,wj9,wj10,wj11:pointer;
{$R *.res}
procedure DLLEntry(reason: DWORD); //dll装载时执行
var
ljj:PChar;
ljj2:string;
DLLHandle: THandle;
pData:pointer;
mbi_thunk: TMemoryBasicInformation;
begin
case reason of
    DLL_PROCESS_ATTACH:
    begin
    ljj:=AllocMem(512);
    GetSystemDirectory(ljj,256);            //获取系统目录
    ljj2:=string(ljj)+'\lpk.dll' ;      //连接"\lpk.dll"
    ljj:=nil;
    FreeMem(ljj);
    DLLHandle := LoadLibrary(PChar(ljj2));
//下面是获取LPK.DLL的输出函数
    wj1:=GetProcAddress(DLLHandle, 'ftsWordBreak');
    wj2:=GetProcAddress(DLLHandle, 'LpkUseGDIWidthCache');
    wj3:=GetProcAddress(DLLHandle, 'LpkPSMTextOut');
    wj4:=GetProcAddress(DLLHandle, 'LpkGetTextExtentExPoint');
    wj5:=GetProcAddress(DLLHandle, 'LpkGetCharacterPlacement');
    wj6:=GetProcAddress(DLLHandle, 'LpkExtTextOut');
    wj7:=GetProcAddress(DLLHandle, 'LpkEditControl');
    wj8:=GetProcAddress(DLLHandle, 'LpkDrawTextEx');
    wj9:=GetProcAddress(DLLHandle, 'LpkDllInitialize');
    wj10:=GetProcAddress(DLLHandle, 'LpkTabbedTextOut');
    wj11:=GetProcAddress(DLLHandle, 'LpkInitialize');
   //下面是修改内存程序段 ,(这段去掉也不能加载,不是下面这段的问题)
    pData := pointer($00403296);
   //查询页信息。
   VirtualQuery(pData, mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
   / /改变页保护属性为读写。
    asm
    push eax
    push edx
    mov eax,$4024E0
    cmp ,$358b6674
    jne @@11
    mov edx,$358b9090
    mov ,edx
    @@11:
    pop edx
    pop eax
    end;

    end;
    DLL_PROCESS_DETACH:
    begin

    end;
end;
end;




procedure ftsWordBreak;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj1
end;
end;

procedure LpkUseGDIWidthCache;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj2
end;
end;

procedure LpkPSMTextOut;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj3
end;
end;

procedure LpkGetTextExtentExPoint;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj4
end;
end;

procedure LpkGetCharacterPlacement;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj5
end;
end;

procedure LpkExtTextOut;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj6
end;
end;


procedure LpkEditControl;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj7
end;
end;


procedure LpkDrawTextEx;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj8
end;
end;

procedure LpkDllInitialize;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj9
end;
end;

procedure LpkTabbedTextOut;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj10
end;
end;

procedure LpkInitialize;stdcall;  //模拟windows的lpk.dll的函数
begin
asm
jmp wj11
end;
end;


exports
ftsWordBreak Index 11,
LpkUseGDIWidthCache Index 10,
LpkPSMTextOut Index 9,
LpkGetTextExtentExPoint Index 8,
LpkGetCharacterPlacement Index 7,
LpkExtTextOut Index 6,
LpkEditControl Index 5,
LpkDrawTextEx Index 4,
LpkDllInitialize Index 3,
LpkTabbedTextOut Index 2,
LpkInitialize Index 1;

begin
DLLProc := @DLLEntry;
DLLEntry(DLL_PROCESS_ATTACH);
end.

先谢谢了!

[ 本帖最后由 johnroot 于 2007-8-20 12:16 编辑 ]

黑夜彩虹 发表于 2007-8-20 10:11:23

标记,回头学习。。。。/:good

Gue 发表于 2007-8-20 20:31:02


    wj1:=GetProcAddress(DLLHandle, 'ftsWordBreak');
    wj2:=GetProcAddress(DLLHandle, 'LpkUseGDIWidthCache');
    wj3:=GetProcAddress(DLLHandle, 'LpkPSMTextOut');
    wj4:=GetProcAddress(DLLHandle, 'LpkGetTextExtentExPoint');
    wj5:=GetProcAddress(DLLHandle, 'LpkGetCharacterPlacement');
    wj6:=GetProcAddress(DLLHandle, 'LpkExtTextOut');
    wj7:=GetProcAddress(DLLHandle, 'LpkEditControl');
    wj8:=GetProcAddress(DLLHandle, 'LpkDrawTextEx');
    wj9:=GetProcAddress(DLLHandle, 'LpkDllInitialize');
    wj10:=GetProcAddress(DLLHandle, 'LpkTabbedTextOut');
    wj11:=GetProcAddress(DLLHandle, 'LpkInitialize');


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


procedure LpkExtTextOut;stdcall; //模拟windows的lpk.dll的函数
begin
asm
jmp wj6
end;
end;

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

[ 本帖最后由 Gue 于 2007-8-20 20:33 编辑 ]

caterpilla 发表于 2007-8-21 09:20:50

有没有C语言版本的参考下?

Gue 发表于 2007-8-21 15:39:38

我的机器有人在用着,这些是在记事本里写的,没有测试过...

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

int MessageBox(          HWND hWnd,
    LPCTSTR lpText,
    LPCTSTR lpCaption,
    UINT uType
);


因此,我们定义函数原型

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

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

MESSAGEBOX _MessageBox;

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

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


int WINAPI MessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
        //在这里做你想做的事
       
        return _MessageBox(hWnd, lpText, lpCaption, uType);
}


//卸载本DLL前卸载掉User32.dll
页: [1]
查看完整版本: delphi编写的外挂型DLL有问题,求助!