分类 技术分享 下的文章

奇葩的编译器 ULONG 为啥要movsx byte ptr?

真的是第一次遇到这种编译器解释,年轻人,见识少啊。

if(*(DWORD*)&nInstructions[0] == 0x878af88bUL)

结果是:

1: kd> u b126f1e5
xxxxxx!TryToX+0x1c5 [e:\drv\xxxx\xxxx.c @ 639]:
b126f1e5 0fbe1590e926b1  movsx   edx,byte ptr [xxxxxx!nInstructions (b126e990)]
b126f1ec 81fa8b000000    cmp     edx,8Bh
b126f1f2 0f8598000000    jne     xxxxxx!TryToHookNtWriteVirtualMemory+0x270 (b126f290)
b126f1f8 0fbe0591e926b1  movsx   eax,byte ptr [xxxxxx!nInstructions+0x1 (b126e991)]
b126f1ff 3df8000000      cmp     eax,0F8h
b126f204 0f8586000000    jne     xxxxxx!TryToHookNtWriteVirtualMemory+0x270 (b126f290)
b126f20a 0fbe0d92e926b1  movsx   ecx,byte ptr [xxxxxx!nInstructions+0x2 (b126e992)]
b126f211 81f98a000000    cmp     ecx,8Ah

从movsx开始我就隐约有点蛋疼了,不是ULONG互相比较吗,为啥要一个字节一个字节的movsx + cmp?接着果然蛋疼了:

1: kd> db nInstructions
b126e990  8b f8 8a 87 40 01 00 00-00 00 00 00 94 53 5b 80  ....@........S[.
b126e9a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
b126e9b0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

果不其然:

Breakpoint 2 hit
xxxxxxx!TryX+0x1c5:
b138b1e5 0fbe1590a938b1  movsx   edx,byte ptr [xxxxxxx!nInstructions (b138a990)]
1: kd> r edx
edx=ffffff8b

条件不满足,然后呢?改成这样就过了,你逗我?

if((ULONG)*(DWORD*)&nInstructions[0] == (ULONG)0x878af88bUL)

这回判断正常了:

1: kd> u b13931e5
xxxxxxx!TryX+0x1c5 [e:\drv\***.c @ 639]:
b13931e5 813d902939b18bf88a87 cmp dword ptr [xxxxxxx!nInstructions (b1392990)],878AF88Bh

闲来无事build一个checked sys试试

元旦看了两天书,正儿八经做一个驱动吧,可惜一编译就跪了……

C:\drivers\firstddk>build
BUILD: Compile and Link for x86
BUILD: Loading e:\winddk\7600.16385.1\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Start time: Sat Jan 03 14:15:05 2015
BUILD: Examining c:\drivers\firstddk directory for files to compile.
BUILD: Saving e:\winddk\7600.16385.1\build.dat...
BUILD: Compiling and Linking c:\drivers\firstddk directory
Configuring OACR for 'root:x86chk' - <OACR on>
_NT_TARGET_VERSION SET TO WINXP
Compiling - mini_ddk.c
1>errors in directory c:\drivers\firstddk
1>e:\winddk\7600.16385.1\inc\api\sal.h(160) : error C1083: Cannot open include f
ile: 'codeanalysis\sourceannotations.h': No such file or directory
Linking Executable - sys\i386\ddk_helloworld.sys
1>link : error LNK1181: cannot open input file 'c:\drivers\firstddk\objchk_wxp_x
86\i386\mini_ddk.obj'
BUILD: Finish time: Sat Jan 03 14:15:06 2015
BUILD: Done

    3 files compiled - 1 Error
    1 executable built - 1 Error

网上的解法也是屌。简单粗暴(via:http://blog.csdn.net/devday/article/details/6683329
f1.png

好哎,终于摆脱vs就给编出来了
f1.jpg

C:\drivers\firstddk>build
BUILD: Compile and Link for x86
BUILD: Loading e:\winddk\7600.16385.1\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Start time: Sat Jan 03 14:19:46 2015
BUILD: Examining c:\drivers\firstddk directory for files to compile.
BUILD: Saving e:\winddk\7600.16385.1\build.dat...
BUILD: Compiling and Linking c:\drivers\firstddk directory
Configuring OACR for 'root:x86chk' - <OACR on>
_NT_TARGET_VERSION SET TO WINXP
Compiling - mini_ddk.c
Linking Executable - sys\i386\ddk_helloworld.sys
BUILD: Finish time: Sat Jan 03 14:19:48 2015
BUILD: Done

    3 files compiled - 69 LPS
    1 executable built

然后就是蓝屏之路了呗
出师未捷身先死,OACR刚一警告就发生了除以零异常
f1.png

f1.png

f2.png

古人诚不欺我也
f1.png

好就好在终于还是成功了,感动涕零
f1.png

上次这么舒爽的时候,还是小学踢球踢坏别人窗户那会儿呢
f2.png

4ab48f3cgw1enfzcof2olj20cf0b50v8.jpg

c的类型提升的一点小测试

之前似乎是在哪儿有听说过,今天听人正式的说了一下,自己测试了测试,果然如此。

代码如下
f2.png

编译之后,运行结果是4,char明显变成了一个int
f1.png

使用DDD跟踪,发现编译器在生成阶段就已经算好sizeof 'A'的值是4,硬编码进去了……
f3.png

相反,如果之前定义char x = 'a'; 最后输出sizeof x,那这时又变成了1。
f4.png

发生提升的时候一般都是在表达式中,低于int的整形提升到int,低于double的浮点提升到double。 这个东西完全取决于编译器,上面第二个例子也是编译器提前算好的,只不过由于明确定义了这个东西的类型,所以编译器算出来的是1。 实际上char+char的时候是先int+int然后裁剪成一个char,看看编译出来的代码即知。