Windows kernel32.dll 仅装配图像素
Windows kernel32.dll only assembly draw pixel
我一直在查看堆栈溢出,但似乎找不到任何东西
kernel32.dll在windows 64位上有什么命令和函数可以在屏幕上绘制单个像素,最好没有user32.dll windows?
原来我的.错了。
win32k.sys does create new syscalls。反过来说,也有道理。
win32k.sys 处理 DirectComposition engine,它类似于 Windows 的桌面和 Windows 管理器:
DirectComposition API 通过 COM 暴露给 Win32 程序,这使得在没有 Visual Studio 的情况下很难使用,因为我们需要完整的 IDL 定义,并在汇编中进行偏移手动在 vtables 中。
它也很抽象,所以 reverse-engineering 使用的系统调用然后使用它们会很痛苦。
但是,GDI,遗留的 Windows' 图形 API,当然仍然受支持(它是用 DirectComposition 模拟的 by/integrated)。
API 通过一些 DLL 的导出函数公开,而不是根据可组合表面工作,而是根据 Windows 和设备上下文(允许绘制的对象)工作。
这使得 reverse-engineering 它和在汇编中使用它变得容易。
最接近在屏幕上绘制像素的是在桌面设备上下文中绘制像素(因为桌面是全屏 window)。
对于 Win32 API,我们将使用两个函数来实现:
GetDC
,当使用 NULL 值调用时给出桌面的设备上下文。
SetPixel
,在设备上下文上绘制一个像素。
如果没有 Win32 API,但只有直接系统调用,它可能会出现问题,因为这些操作不存在于 lower-level 接口上。
例如,此接口可以公开一个共享内存区域,其中使用未记录的格式写入像素。
类似地,设备上下文可以是 Win32 抽象。
但幸运的是,并非如此,GetDC
和 SetPixel
都有自己的系统调用。
这是非常幸运的,可能源于 win32k.sys 的历史(它与 Win32 API 结合得更多,实际上是 Win32 API,IIRC)。
我 reverse-engineered 这两个 Win32 API 来获取系统调用编号以及它们的使用方式(这两个编号都可以在这个答案的第二个 link 中找到)。
虽然 GetDC
只是系统调用的包装器,但 SetPixel
对颜色进行了一些格式转换。
在下面给出的例子中,这个转换被省略了,如果需要的话由你决定(没有它你可能无法写出你想要的颜色)。
我做了一个示例程序,在屏幕的左上角绘制了一个黑色的 256x256 矩形。
一些注意事项:
- 是64位程序,可以使用
syscall
指令。这只是为了展示(并且避免解释 WOW32Reserved
指针和 WOW64 是什么以及如何使用它们)。
- 如果程序无法获取桌面句柄,将触发调试异常。
- 在顶部,有用于系统调用编号的常量,它们设置为 Windows 7(如果有的话,不确定是哪个确切的次要版本)。
- 程序是用 NASM 组装的,link 用 golink 编辑的。
- 这是一个很无聊的节目。避免 Win32 API 不会为编程增加任何洞察力。如果我是你,我会使用 API.
没有外部 PE 依赖项:
DEFAULT REL
GLOBAL main
%define SYS_GetDC 100ah
%define SYS_SetPixel 10afh
SECTION .text
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Get the HDC of a window
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;arg0 (rcx) = HWND
GetDC:
mov r10, rcx
mov eax, SYS_GetDC
syscall
ret
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Set a pixel in an HDC
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
SetPixel:
mov r10, rcx
mov eax, SYS_SetPixel
syscall
ret
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Main
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
main:
;Get the desktop HDC
xor ecx, ecx
call GetDC
test eax, eax
jz .abort
;Write a 256x256 black square
mov ebx, eax ;HDC into rbx (which is preserved)
xor esi, esi ;esi = x = 0
.x_loop:
xor edi, edi ;edi = y = 0
.y_loop:
mov ecx, ebx ;HDC
mov edx, edi ;Y
mov r8, rsi ;X
xor r9, r9 ;Color (black, beware of the correct format!)
call SetPixel
inc edi ;y++
cmp edi, 100h
jb .y_loop ;while (y < 256)
inc esi ;x++
cmp esi, 100h
jb .x_loop ;while (x < 256)
;In Windows we can return from main
ret
;Here something went wrong
;We must do some eye-catching action, like invoking the debugger
.abort:
;This will trigger a debug popup
int3
我一直在查看堆栈溢出,但似乎找不到任何东西
kernel32.dll在windows 64位上有什么命令和函数可以在屏幕上绘制单个像素,最好没有user32.dll windows?
原来我的
win32k.sys does create new syscalls。反过来说,也有道理。
win32k.sys 处理 DirectComposition engine,它类似于 Windows 的桌面和 Windows 管理器:
DirectComposition API 通过 COM 暴露给 Win32 程序,这使得在没有 Visual Studio 的情况下很难使用,因为我们需要完整的 IDL 定义,并在汇编中进行偏移手动在 vtables 中。
它也很抽象,所以 reverse-engineering 使用的系统调用然后使用它们会很痛苦。
但是,GDI,遗留的 Windows' 图形 API,当然仍然受支持(它是用 DirectComposition 模拟的 by/integrated)。
API 通过一些 DLL 的导出函数公开,而不是根据可组合表面工作,而是根据 Windows 和设备上下文(允许绘制的对象)工作。
这使得 reverse-engineering 它和在汇编中使用它变得容易。
最接近在屏幕上绘制像素的是在桌面设备上下文中绘制像素(因为桌面是全屏 window)。
对于 Win32 API,我们将使用两个函数来实现:
GetDC
,当使用 NULL 值调用时给出桌面的设备上下文。SetPixel
,在设备上下文上绘制一个像素。
如果没有 Win32 API,但只有直接系统调用,它可能会出现问题,因为这些操作不存在于 lower-level 接口上。
例如,此接口可以公开一个共享内存区域,其中使用未记录的格式写入像素。
类似地,设备上下文可以是 Win32 抽象。
但幸运的是,并非如此,GetDC
和 SetPixel
都有自己的系统调用。
这是非常幸运的,可能源于 win32k.sys 的历史(它与 Win32 API 结合得更多,实际上是 Win32 API,IIRC)。
我 reverse-engineered 这两个 Win32 API 来获取系统调用编号以及它们的使用方式(这两个编号都可以在这个答案的第二个 link 中找到)。
虽然 GetDC
只是系统调用的包装器,但 SetPixel
对颜色进行了一些格式转换。
在下面给出的例子中,这个转换被省略了,如果需要的话由你决定(没有它你可能无法写出你想要的颜色)。
我做了一个示例程序,在屏幕的左上角绘制了一个黑色的 256x256 矩形。
一些注意事项:
- 是64位程序,可以使用
syscall
指令。这只是为了展示(并且避免解释WOW32Reserved
指针和 WOW64 是什么以及如何使用它们)。 - 如果程序无法获取桌面句柄,将触发调试异常。
- 在顶部,有用于系统调用编号的常量,它们设置为 Windows 7(如果有的话,不确定是哪个确切的次要版本)。
- 程序是用 NASM 组装的,link 用 golink 编辑的。
- 这是一个很无聊的节目。避免 Win32 API 不会为编程增加任何洞察力。如果我是你,我会使用 API.
没有外部 PE 依赖项:
DEFAULT REL
GLOBAL main
%define SYS_GetDC 100ah
%define SYS_SetPixel 10afh
SECTION .text
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Get the HDC of a window
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;arg0 (rcx) = HWND
GetDC:
mov r10, rcx
mov eax, SYS_GetDC
syscall
ret
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Set a pixel in an HDC
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
SetPixel:
mov r10, rcx
mov eax, SYS_SetPixel
syscall
ret
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
;
;Main
;
;. . . . . . . . . . . . . .
; . - . - . - . - . - . - . - . - . - . - . - . - . -
main:
;Get the desktop HDC
xor ecx, ecx
call GetDC
test eax, eax
jz .abort
;Write a 256x256 black square
mov ebx, eax ;HDC into rbx (which is preserved)
xor esi, esi ;esi = x = 0
.x_loop:
xor edi, edi ;edi = y = 0
.y_loop:
mov ecx, ebx ;HDC
mov edx, edi ;Y
mov r8, rsi ;X
xor r9, r9 ;Color (black, beware of the correct format!)
call SetPixel
inc edi ;y++
cmp edi, 100h
jb .y_loop ;while (y < 256)
inc esi ;x++
cmp esi, 100h
jb .x_loop ;while (x < 256)
;In Windows we can return from main
ret
;Here something went wrong
;We must do some eye-catching action, like invoking the debugger
.abort:
;This will trigger a debug popup
int3