首页
社区
课程
招聘
Delphi编译器生成代码问题
2004-4-29 12:19 7090

Delphi编译器生成代码问题

2004-4-29 12:19
7090
Delphi编译器生成代码问题
kongfoo/2004.4.29
版本:7.0 build 4.453(D版)
以前写代码时就遇到过ReadFile不能成功调用的问题,都是不了了之。
今天又要用ReadFile,跟踪一下发现是编译器生成代码出问题了。
调用代码:
pMem:=GlobalAlloc(...);
ReadFile(hFile,pMem,fileSize,readed,nil)
第二个参数是缓冲区的handle,按理说这样的调用应该成功,但编译
生成的代码却是这样:
lea eax,[ebp-x]
push eax
传入的却是放handle的地址。把lea改成mov才能成功调用。
完整代码:
  try
    hFile:=CreateFile(pchar(cb1.Text),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
    fileSize:=GetFileSize(hFile,nil);
    pMem:=GlobalAlloc(GMEM_FIXED + GMEM_ZEROINIT,fileSize);
    asm   //编译器生成的ReadFile有BUG,要改它的代码才能调用成功
      call @@1
     @@1:
      pop eax
      mov memAddr,eax
    end;
    VirtualQuery(pointer(memAddr),mbi,1024);
    VirtualProtect(pointer(memAddr),1024,PAGE_READWRITE,@mbi);
    asm
      call @@2
     @@2:
      pop eax
      mov byte ptr [eax+12],$8b   //打补丁后传入ReadFile的才是正确参数
    end;
    ReadFile(hFile,pMem,fileSize,d,nil);
  finally
    GlobalFree(pMem);
    CloseHandle(hFile);
  end;

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞7
打赏
分享
最新回复 (5)
雪    币: 396
活跃值: (1078)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
simonzh2000 24 2004-4-29 12:41
2
0
KongFoo 兄要用 Delphi 写加壳器了?

昨天我也发现一个Bug.
OD 1.10C CPU 窗口进入动态生成的 Memory 时,
不能用鼠标右键,  OD 1.10B 可以.
雪    币: 274
活跃值: (165)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
老王 1 2004-4-29 13:01
3
0
function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
  var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

类似var Buffer这样的参数不能传入指针!你比较一下Move和CopyMemory传入参数的方法。

这样用试试:
var
  pMem: Pchar;
...
pMem:=GlobalAlloc(...);
if pMem <> nil then
  ReadFile(hFile,pMem^,fileSize,readed,nil);
雪    币: 371
活跃值: (790)
能力值: ( LV12,RANK:570 )
在线值:
发帖
回帖
粉丝
kongfoo 14 2004-4-29 14:16
4
0
最初由 simonzh2000 发布
KongFoo 兄要用 Delphi 写加壳器了?

昨天我也发现一个Bug.
OD 1.10C CPU 窗口进入动态生成的 Memory 时,
不能用鼠标右键, OD 1.10B 可以.


菜啊,要把yoda的汇编码移置成Delphi的代码可不是我这样水平能完成的 :(
想用Delphi写个API地址查询器。
新版OD是有点问题,问题出在4206bd的ollydbg._Findmodule。

最初由 老王 发布

function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

类似var Buffer这样的参数不能传入指针!你比较一下Move和CopyMemory传入参数的方法。

这样用试试:
var
pMem: Pchar;
...
pMem:=GlobalAlloc(...);
if pMem <> nil then
ReadFile(hFile,pMem^,fileSize,readed,nil);

经你指点我知道问题的原因啦,但还是解决不了。
GlobalAlloc返回的是cardinal,这样用是编译不了的。
雪    币: 274
活跃值: (165)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
老王 1 2004-4-29 22:01
5
0
GlobalAlloc返回的是cardinal,当然编译不通过了,我想成是VirtualAlloc了,你试试ReadFile(hFile, Pointer(pMem)^, ...);行不行,不过我不知道这里为什么要用GlobalAlloc?
我一般这样写:
var
  pMem: Pointer;
...
  GetMem(pMem, fileSize);
  ...
  ReadFile(hFile, pMem^, ...);
  ...
  FreeMem(...);
这样应该也行:
var
  Buf: array of Char;
...
  SetLength(Buf, FileSize);//一般来说,DELPHI编译器会帮你释放内存
  ...
  ReadFile(hFile, Buf, ...);  
  ...
雪    币: 371
活跃值: (790)
能力值: ( LV12,RANK:570 )
在线值:
发帖
回帖
粉丝
kongfoo 14 2004-4-30 08:39
6
0
最初由 老王 发布
GlobalAlloc返回的是cardinal,当然编译不通过了,我想成是VirtualAlloc了,你试试ReadFile(hFile, Pointer(pMem)^, ...);行不行,不过我不知道这里为什么要用GlobalAlloc?
我一般这样写:
var
pMem: Pointer;
...
GetMem(pMem, fileSize);
...
ReadFile(hFile, pMem^, ...);
...
FreeMem(...);
这样应该也行:
var
Buf: array of Char;
...
SetLength(Buf, FileSize);//一般来说,DELPHI编译器会帮你释放内存
...
ReadFile(hFile, Buf, ...);
...


测试过了,转换成指针和申请内存都行。字符数组也要ReadFile(hFile,Pointer(Buf)^,...);这样才行。
Thanks老王
游客
登录 | 注册 方可回帖
返回