首页
社区
课程
招聘
[注意]关于Delphi驱动开发跨单元变量引用的说明
发表于: 2010-1-2 20:18 8460

[注意]关于Delphi驱动开发跨单元变量引用的说明

2010-1-2 20:18
8460

由于易博龙接手Delphi后,对编译器做了些修改,导致Delphi7以后的版本跨单元变量引用发生了改变,现举例说明如下:

unit Unit1;

interface

uses 
  nt_status, ntoskrnl, unit2;

function _DriverEntry(pDriverObject: PDriverObject; RegistryPath: PUnicodeString) : NTSTATUS; stdcall;

implementation

procedure DriverUnload(pDriverObject: PDriverObject); stdcall;
begin

end;

function _DriverEntry(pDriverObject: PDriverObject; RegistryPath: PUnicodeString) : NTSTATUS; stdcall;
begin
  asm
    int	3;
  end;
  pDriverObject^.DriverUnload := @DriverUnload;
  test1 := 100;
  ChangeOffset;
  test3 := $3A3A;               

  DbgPrint('offset %d, test1=%d, test2=%d, test3=%d'#13#10, ShareNameOffset, test1, test2, test3);
  recTest.b := $7F7F;
  DbgPrint('myRec.a = %d, myRec.b = %d'#13#10, recTest.a, recTest.b); 
  Result:= STATUS_SUCCESS;
end;

end.
unit Unit2;

interface

uses 
  nt_status, ntoskrnl;
  
type
  myRec = packed record
    a: integer;
    b: integer;
  end;

var
  ShareNameOffset: ULONG = 0;    //全局变量
  test1: DWORD;
  test2: DWORD = 1000;
  test3: DWORD;
  recTest: myRec = (a:10; b:100);

procedure ChangeOffset;

implementation

procedure ChangeOffset;
begin
  ShareNameOffset:= $ABC;     //修改
 test2 := $2000;
  recTest.a := $1A1A;
  recTest.b := $2A2A;
end;

end.
                public start
start           proc near

arg_0           = dword ptr  8

                push    ebp
                mov     ebp, esp
                int     3               ; Trap to Debugger
                mov     eax, [ebp+arg_0]
                mov     dword ptr [eax+34h], offset sub_10280
                mov     dword_103B4, 64h ; test1 := 100
                call    sub_10344
                mov     dword_103B8, 3A3Ah ; test3 := 3A3A
                mov     eax, dword_103B8
                push    eax
                mov     eax, dword_103A4
                push    eax
                mov     eax, dword_103B4
                push    eax
                mov     eax, dword_103A0
                push    eax
                push    offset Format   ; "offset %d, test1=%d, test2=%d, test3=%d"...
                call    DbgPrint
                add     esp, 14h
                mov     eax, 7F7Fh
                mov     dword_103AC, eax ; recTest.b := $7F7F
                push    eax
                mov     eax, dword_103A8
                push    eax
                push    offset aMyrec_aDMyrec_ ; "myRec.a = %d, myRec.b = %d\r\n"
                call    DbgPrint
                add     esp, 0Ch
                xor     eax, eax
                pop     ebp
                retn    8
start           endp

dword_103A0     dd 0   
                       
dword_103A4     dd 3E8h
                       
dword_103A8     dd 0Ah 
                       
dword_103AC     dd 64h 
                       
                db    0
                db    0
                db    0
                db    0
dword_103B4     dd 0   
                       
dword_103B8     dd 0

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
2
非结构体变量也成了指针?!这个改动还真不知道,找时间试试...
不过指针像这样操作就很有点麻烦
lea eax, sseh
mov (_SEH PTR [eax]).xxx, yyy

以前结构体操作 mov sseh.xxx, yyy 这样用还是很爽的。

{$ifdef VER150}
2010-1-3 00:08
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
3
是的,你看我上面贴的代码,普通变量也成了指针,我也没弄明白易博龙为什么要这样做,对比d2010和d7生成的代码,就感觉d2010的明显要拖沓很多。不过也只能慢慢适应了,不可能永远抱着delphi7不放,毕竟D2010里的很多新特性是非常诱人的。
2010-1-3 00:18
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
4
这个可能是D2010新改成这样的,D2009中都还能这样用:
Unit1.pas.38: stTest.bA := 1;
0040A7A1 C605841D410001 mov byte ptr [$00411d84],$01 ; bA类型为BYTE,默认2字节对齐
Unit1.pas.44: mov ax, $4321
0040A7BC 66B82143 mov ax,$4321
Unit1.pas.45: mov stTest.wB, ax
0040A7C0 66A3861D4100 mov [$00411d86],ax


D2010这边机器还没装,主要是不习惯启动前还要加载那个破解用bpl(目前Update3好像只能用这个方法进去)。感觉D2010中这样修改可能是为了后期扩展,难道以后所有变量都可以运行期改变类型?(比如原先定义一个DWORD,后面不够用了想扩展成array[0..1] of DWORD的话,只用把指针移向新的地方就够了。而原来那种方式显然做不到这样的操作)
纯属胡猜 不过相信Delphi的编译器只会越改越好,我们拭目以待吧。
2010-1-3 09:12
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
5
是这样的,比如你在unit1里定义一个公共变量test1,unit1里的程序引用test1的时候是直接对test1操作,而如果你在其他单元里引用test1的话,则会通过一个指向test1的指针对其进行操作,我试过Delphi2007、Delphi2009都是这样做的^_^
2010-1-3 13:35
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
6
哦,跨单元是这个意思,重新试了一下D2009,确实如此:
test.dpr.65: [B]stTest.wB := 2;[/B]
0040B196 A1FCCA4000       mov eax,[$0040cafc]         ; $0040cafc 是存放 stTest 实际位置$00411d84的指针
0040B19B 66C740020200     mov word ptr [eax+$02],$0002

跨单元后,Delphi 2009直接编译能识别 mov stTest.wB, ax 这样的操作,是因为他完全按照内嵌汇编写的内容转换成非指针的形式:
test.dpr.68: [B]mov stTest.wB, ax[/B]
0040B19B 66A3861D4100     mov [[COLOR="Red"]$00411d86[/COLOR]],ax        ; 这里直接由编译器将stTest.wB转换成地址$00411d84+2了,确实很终于“原著”

而直接写的 stTest.wB := xxx; 这个跨单元操作,则可能按照新编译器的规则转成了指针方式。

跨单元全局变量,好隐蔽的问题...
2010-1-3 19:45
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
7
哈哈,这个隐蔽的问题害的我的rmcoff2修改了无数次,不过现在终于搞定了^_^
2010-1-3 20:44
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=mickeylan;738748]哈哈,这个隐蔽的问题害的我的rmcoff2修改了无数次,不过现在终于搞定了^_^

2010.01.02 -- 彻底解决Delphi7以后版本跨单元变量引用问题,并于跨单元变量引用的详细说明请参阅:http://www.kmdkit4d.net/dispbbs.do?boardId=8&ID=123&star=1
[/QUOTE]

这么快就搞定了?恭喜
2010-1-4 22:58
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
9
对嵌入式汇编我就无能为力了,这个就要靠写程序的人了,别的都搞定了^_^
2010-1-5 00:22
0
雪    币: 12688
活跃值: (4294)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
学习一下~~写驱动蓝到怕了~~
2010-1-5 05:23
0
雪    币: 109
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
delphi牛人啊,,,羡慕ing.....
2010-1-5 10:28
0
游客
登录 | 注册 方可回帖
返回
//