Add assembly code to the 64-bit driver

Source: Internet
Author: User

This document describes how to call the Assembly functions exported from the ASM file in the C file of the driver.
Introduction
The windows driver uses ddk1_ifsddk(compile and link the source file with the build.exe program in the simple name ddk1_. during the operation, you only need to start the corresponding DDK command line program, enter the source file directory to be compiled, and run the build command to obtain the. SYS file.
A nmakeprogram is used on the buildcommand. cl.exeand link.exe are used as the nmakeprogram and all compilation and link options are specified. Different from the application, programmers cannot modify the compilation link options when using the build command, therefore, the build command cannot intervene in the compilation or link process.
The 64-bit platform no longer supports embedded assembly code. To enable the driver to still use the assembly language, the usual practice is to write the assembly code into an independent function and put it into a separate Assembly file, compile the Assembly file to form an OBJ file, and then link all the target files (including the target files driving the C code) during the link period. However, the built-in build program of DDK does not directly support Compilation and linking of assembly files (or I have not found such a method ). Therefore, you need to use other means to link the Assembly Code target file with the C Code target file. The method described in this article is to call an independent assembler function in a Windows Driver by modifying the source file and forcing the specified external function call convention.
Notes
Differences in the call conventions between the 1.32-bit platform and the 64-bit Platform
On the 32-bit platform, the driver uses the _ stdcall call Convention by default. The function names generated by the compilation Convention are suffixed with @ xxx, and the Assembly Code uses the _ cdecl call convention, the function name compiled by the assembler does not contain a suffix, so that C code cannot reference the function in the Assembly file (the linker reports the error unresolved external asm_rng_available @ xxx ). The method to solve this problem is to forcibly specify the calling of external assembler functions as the _ cdecl call Convention. That is, if the asm_rng_available function in the Assembly file is called in the C file, the declaration method should be as follows:
Extern int _ cdecl asm_rng_available ();
After the _ cdecl call convention is forcibly specified, the asm_rng_available function generated by the C compiler and the function name generated in the Assembly file are the same.
In the 64-bit architecture, only one local call convention and one _ cdecl convention can be ignored by the compiler. Other Call conventions have been cleared, therefore, the name of the function generated by the 64-bit DDK compiler is the same as that generated by the assembler. The function name does not have a suffix and therefore does not need to be modified. That is, if the asm_rng_available function in the Assembly file is called in the C file, the declaration method is as follows:
Extern int asm_rng_available ();


2. Modify the source file
Because the build command does not automatically associate the target file of the Assembly file, you can specify it in the targetlibs macro of the source file to link the compiled compilation target file to the C target file. The specific method is as follows:
Targetlibs =. \ instr_32.obj
In this way, you can use the build command to directly link all the target files.
Differences between some system calls in 3.64 bits and 32 bits
The LIB library in the 64-bit DDK does not export the keinitializespinlock and kequeryinterrupttime functions. Therefore, the function pointer must be obtained through mmgetsystemroutineaddress and called using the function pointer.
Call assembly functions in Driver
The following describes the entire process:
1. Place the Assembly file and the c file of the driver in the same directory (for short, the driver directory );
2. Modify the source file and add targetlibs = *. OBJ to the source file. * indicates the name of the Assembly file (without the extension );
3. Declare the function name of the external Assembly file in the driver C file. If it is a 32-bit architecture, the Assembly function must be specified as _ cdecl when declaring the function;
4. Compile the Assembly file and generate the OBJ target file under the driver directory (the compiler can use NASM or MASM );
5. Run the build command on the entire driver project in the DDK compiling environment to generate the. SYS file.
OK...

For the C language, you can directly compile the 64-bit platform in the vs2005.net environment. There are many articles to note, so we will not repeat them here.

A. for assembly languages, you must first note that they must be in the pure Assembly format (*. ASM file) or intrinsic Instruction format. Secondly, on the 64-bit platform, we do not recommend using the NASM Compiler (I did not find its support for 64-bit compilation). Instead, we recommend using yasm, this assembly compiler is generated on the basis of NASM, can be said to be compatible with the functions of NASM, and support 64-bit compilation, detailed introduction and relevant download see: http://www.tortall.net/projects/yasm/

Note: You can use ml64.exe in visual studioto compile 64-bit Assembly source files:

Example:

B. The x86-64 has eight more general registers than the x86-32, and each general register is 64-bit wide and they are:
Rax, RBx, rcX, RDX, RSI, RDI, RSP, RBP
R8, R9, R10, R11, R12, R13, R14, R15

At the same time, the x86-64 fully supports General registers for x86-32 and x86-16:
Eax, ax, Al, ah,
EBX, BX, BL, BH,
However,When performing inbound/outbound stack operations on registers, only the corresponding 64-bit registers can be inbound/outbound., That is:
(Instructions that modify the stack (push, Pop, call, RET, enter, and leave) are implicitly 64-bit. their 32-bit counterparts are not available, but their 16-bit counterparts are. examples in NASM Syntax:
Push eax; illegal instruction
Push RBx; 1-byte instruction
Push R11; 2-byte instruction with Rex prefix)

C. x64 call conventions:

During the design of the call schedule, the x64 architecture uses the opportunity to clear the confusion of existing Win32 call conventions (such as _ stdcall, _ cdecl, _ fastcall, and _ thiscall. In win64, only one native call Convention and modifiers such as _ cdecl are ignored by the compiler. In addition, reducing the call conventions also brings debugging benefits.

The main content of the x64 call convention you need to know is: Its similarities with the x86 fastcall convention. In x64 conventions, the first four Integer Parameters (from left to right) are passed into the specified 64-bit register:

RcX: 1st integer argument the first parameter is stored in the rcX register
The second parameter of the RDX: 2nd integer argument is stored in the rcX register.
R8: 3rd integer argument the third parameter is stored in the rcX register
R9: 4th integer argument fourth parameter stored in rcX register

Integer Parameters other than the first four are passed to the stack.. This pointer is regarded as an integer parameter, so it is always in the rcX register.For floating-point parameters, the first four parameters are passed into xmm0
Xmm3 registers. Subsequent floating point parameters will be placed on the thread stack.

Further explore the call conventions. Even if a parameter can be passed into a register, the compiler can still reserve space for it by consuming the RSP register on the stack. At least, each function must reserve 32 bytes (4 64-bit values) on the stack ). This space allows you to easily copy registers of input functions to known stack locations. It is not required that the called function overflow the input register parameter to the stack, but when necessary, the stack space is reserved to ensure that it can do so. Of course,If you want to pass
If there are more than four Integer Parameters, additional stack space must be reserved.

Let's look at an example. Consider a function that passes two Integer Parameters to a subfunction. The compiler not only assigns the value to rcX and RDX, but also deducts 32 bytes from the RSP Stack pointer register.In the called function, parameters can be accessed in registers (rcX and RDX.If the called code requires registers for other purposes, you can copy the registers to the reserved 32-byte stack area. Figure 6 shows the registers and stacks after passing 6 integer parameters.

Figure 6 passing Integers

Apply pressure to the parameter stack,It must be noted that (for Integer Parameters ):
1. parameters after the fourth parameter are pushed to the stack in reverse order (8 bytes)
2. The 32 bytes reserved for the first four parameters occupy a fixed space and are pre-allocated. They are not the responsibility of the function caller. That is to say, whether you use them or not, this part of the stack space is occupied, and RSP points to the position shown in.
So for the above example, if the call function is important to access P5, the correct method of P6 is:
MoV eax, [esp + 32 + 8]; P5
MoV EBX, [esp + 32 + 16]; p6

D,A very special register rip, equivalent to the eip of the x86-32. in the x86-32 is not directly accessible, such as mov eax, EIP is wrong, but in the x86-64 bit but can, such as mov, rax, qword
PTR [RIP + 100] is correct
. Besides a program counter, it is also a "Data Base Address". It can be seen that it is now in two roles! Why use RIP as the base address for data access in the x86-64 bit? Because, in the x86-64, DS, es, Cs, SS have no practical significance, that is, they are no longer involved in address computing, just to be compatible with the x86-32. FS, Gs is still involved in address computing, and both of them have the same meaning as the x86-32. Because ds, es, Cs, and SS are meaningless, symbol variables are not allowed to appear directly in assembly code during dynamic library compilation, but must be used together with Rip, that is
MoV rax, [symb WRT Rip] or Lea RBx, [symb WRT Rip]

Reference webpage:
Amd64 Architecture --- http://www.tortall.net/projects/yasm/wiki/AMD64
All the information you need to know before you start programming 64-bit windows-http://www.microsoft.com/china/MSDN/library/Windev/64bit/issuesx64.mspx? MFR = true
The history of calling conventions, Part 5: amd64 --- http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx



Trackback: http://tb.blog.csdn.net/TrackBack.aspx? Postid = 1371665

The following is an example code:

An addition function is implemented in the Assembly to implement four parameters passed in, which correspond to the first rcX parameter, second RDX parameter, third R8 parameter, and fourth R9 parameter.

X64asm. ASM file name

. Code
Addsub proc
Push rcX

Add rcX, RDX
Add rcX, R8
Add rcX, R9
MoV rax, rcX

Pop rcX
RET
Addsub endp
End

Call the addition function provided by assembly code in the driver: addsub

X64asmdriver. C source file name

# Include <ntddk. h>

Extern int addsub (pvoid, pvoid );

Void driverunload (in pdriver_object driverobject)
{
Kdprint ("driverunload OK! \ N "));
}

# Pragma code_seg ("init ")
Ntstatus
DriverEntry (
In pdriver_object driverobject,
In punicode_string pregpath
)
{
Ulong32 nresult = 0;
Ulong32 A = 10;
Ulong32 B = 20;
Ulong32 c = 30;
Ulong32 d = 40;

Driverobject-> driverunload = driverunload;

Nresult = addsub (A, B, C, D );
Kdprint ("nresult = % d \ n", nresult ));

Return STATUS_SUCCESS;
}

Note: For driver source file configuration, add the OBJ file generated by assembly to targetlibs =. \ x64asm. obj.

Targetname = x64asmdriver
Targettype = driver
Targetlibs =. \ x64asm. OBJ

Sources = x64asmdriver. c

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.