win32 masm32 汇编学习 及 远程线程实例
"门“ 指向某个优先级高的程序所规定的入口点,所有优先级低的程序调用优先级高的程序只能通过门重定向
门:中断门,自陷门,任务门。
masm32.zip
copy D:\Program Files\Microsoft Visual Studio\VC98\Bin\nmake.exe to ***\masm32\bin
相应cmd设置临时环境变量
@echo off
set include=f:\masm32\Include;D:\Program Files\Microsoft Visual Studio\VC98\Include;D:\Program Files\Microsoft Visual Studio\VC98\MFC\Include
set lib=f:\masm32\lib
set path=f:\masm32\bin;%path%
@echo on
\**\nmake
.model flat MASM自动为各段寄存器做了如下定义:
ASSUME cs:FLAT,ds:FLAT,ss:flat,es:flat,fs:error,gs:error
全部段源程序结构:
.386
.model flat,stdcall
option casemap:none
< Include 文件定义>
.stack [堆栈段大小]
.data
<一些初始化过的变量定义>
.data? ;不会占用EXE文件空间
<一些没初始化过的变量定义>
.const
<一些常量定义>
.code
<代码>
<开始标号>
<其他语句>
end 开始标号
invoke 不是80x86的伪指令,它只是MASM编译器的伪指令,实现push参数和call函数名而已。
对汇编而言,所有参数和返回值 只有一个dword类型,所以要么是简单类型,要么是指针。
返回值放在eax中
函数名 proto [距离] [语言] [参数1]:数据类型,[参数2]:数据类型,....
proto:函数声明伪指令
距离:NEAR,FAR...(WIN32只有只有一个平坦的段,无所谓距离,所以忽略)
语言:.model定义的默认值
对于WIN32它只关注参数个数,参数名为是提高可读性
MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword
MessageBox Proto :dword,:dword,:dword,:dword
其实这两定义是一样的
只有windows NT才完全支持Unicode,
if UNICODE
MessageBox equ <MessageBoxW>
else
MessageBox equ <MessageBoxA>
endif
//@@做标号
@F本指令后第一个@@标号,@B本指令前的第一个@@标号
如果要定义两个字符串"hello,world!",和"hello agin",则每个字符串后跟回车和换行符,最后以一个0字符结尾,
szText db 'hello,world!',0dh,0ah,'hello agin',0dh,0ah,0
.data? 后面的默认是0,不是随机的 //与这全局变量不同,local后的局部变量起始值是随机的
MASM用local伪指令来定义局部变量,local伪指令必须proc伪指令后,其他指令开始前。因为变量数量要早确定下来
结构构成员引用:
1: mov eax,strutname.lpfn
2: mov esi,offset strutname
mov eas,[esi+STRUTNAME.lpfn]
3: mov esi,offset strutname
assume esi:ptr STRUTNAME
mov eax,[esi].lpfn
...
assume esi:nothing
.data
bTest1 db 12h
wTest2 dw 1234h
mov ax,bTest1 ;ax = 3412h
movzx ax,bText1 ;ax = 0012h movsx:带符号扩展
sizeof/lengthof伪指令
如果hello world分两行定义:
szHello db 'hello',odh,oah
db 'world',0
sizeof szHello为7,原因masm中变量只认一行,db 'world',0 实际上是没有名称的数据定义。
获取变量地址:
全局变量:mov 寄存器,offset 变量名 ;编译时
局部变量:lea 寄存器,[ebp-4] ;运行时
参数局部变量:addr 参数变量
对局部变量取地址的时候,addr伪操作只能用在invoke的参数中,addr实际是先取地址到eax,再代替到参数里
invoke Test,eax,addr szHello ;错误
翻译如下:
lea eax,addr szHello
push eax
push eax ;已经被上面覆盖
call Test
invoke Test,addr szHello,eax ;正确
子程序的定义:
子程序名 proc [...][...][VARARG]
local 局部变量列表
指令
子程序名 endp
proc后的参数列表中参数不能和全局变量及子程序中局部变量重名,VARARG指些子程序是可变参数;proto为声明,如上
调用约定有:C, SysCall,StdCall,BASIC,FORTRAN,PASCAL具体找度娘
条件测试语句:==, != , >,>=,<,<=,&,!,&&,||
限制:左边只能是变量或者寄存器,不能是常量;
表达式两边不能同时为变量,但可以同时为寄存器。
分支语句:.if/.elseif/.else/.endif,如果不加点,则变成条件汇编伪操作
循环语句:
.while 条件测试表达式
指令
[.break [.if 退出条件]]
[.continue]
.endw
或者
.repeat
指令
[.break [.if 退出条件]]
[.continue]
.until 条件测试表达式 (或.untilcxz [条件测试表达式])
上面的相当while循环,下面的相当do...while循环
代码规范:
参数用_开头,局部变量用@开头,内部子程序用_开头
尽量不要用宏定义,以免影响可读性
子程序规模不要太大,注释写好,指针安全检查,做好子程序库以备未来编写大程序。
第四章:第一个窗口程序
模块句柄在数值上等于程序在内存中装入的起始地址,GetMododuleHandle,模 块句柄便于访问程度中的各种资源。
postmessage/sendmessage:
当消息中用到指针时,postmessage函数来发送的消息都不会成功。
10.1.4
windows的“堆”分为默认堆和私有堆两种。默认堆是在程序初始化时由OS自动创建的,所有的标准的内存管理函数都是在默认堆中申请内存的;而私有堆相当于是在默认堆中保留了一大块内存,
默认堆只有一个私有堆可以有多个,默认堆可以直接使用,而私有堆必须先创建。
如果多个模块在默认堆中使用内存会交叉排序,一个模块越界可以很难找到问题,如果多个模块在各自的私有堆,越界更容易定位。
私有堆创建函数heapcreate/heapdestory
私有堆中分配和释放内存块heapalloc/heaplock/....
在程序运行的时候,进程中每个地址都可以牌下列3种状态的1种中:
占用状态:线程地址已映射物理内存,也称已提交状态
自由状态:没有映射到物理内存,线程地址没有被使用 //进程刚开始的起始状态
保留状态:虽然没有映射到物理内存,但它不会被使用,直到希望使用他为止
当使用上面的标准内存管理函数时,用户无法指定内存位于哪个线程地址,使用virtual开头的虚拟内存管理函数可以做到这一点。如virtualalloc
VirtualAllocEx/CreateRemoteThread相比 Virtualalloc/createthread多了个hprocess,针对相应进程操作
virtualallocex需要对相应进程有process_vm_operation权限
远程线程存在:重定位和函数的导入问题
对高级语言不可能解决重定位问题,因为没办法在机器码级别上操作,c语言也没有办法,通过注入dll绕过去,因为装载DLL会自动重定位
dwVar dd ?
call @F
@@:
pop ebx
sub ebx,offset @B
mov eax,[ebx+offset dwVar]
:00401000 00000000 BYTE 4 DUP(0)
:00401004 EB00000000 call 00401009
:00401009 5B pop ebx
:0040100A 81EB09104000 sub ebx,00401009
:00401010 8B8300104000 mov eax, dword ptr [ebx+00401000]
当这段代码移动00401000的位置时如下:
:00801000 00000000 BYTE 4 DUP(0)
:00801004 EB00000000 call 00801009
:00801009 5B pop ebx //此时ebx为:00801009
:0080100A 81EB09104000 sub ebx,00401009
:00801010 8B8300104000 mov eax, dword ptr [ebx+00401000]
远程代码用的win32 api,api又存在于是dll中,同时dll装载基地不同,api函数地址也不同,所以手动完成:
1. loadlibary 使用的dll
2. getprocaddress api函数
其中1,2用到dll名字和api函数名都要采用上面重定位的方法保存好
远程线程创建步骤:
1.VirtualAllocEx申请目标进程的一块内存, 要有hProcess有 PROCESS_VM_OPERATION, 内存块应该有PAGE_EXECUTE_READWRITE属性
2.writeProcessMemory写入代码及数据
3.CreateRemoteThread 要hProcess有PROCESS_CREATE_THREAD权限
//remotethread code and data
; RemoteCode.asm
; 一段自定位的代码,可以用来创建一个窗口
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
REMOTE_CODE_START equ this byte_lpLoadLibrary dd ? ;导入函数地址表
_lpGetProcAddress dd ?
_lpGetModuleHandle dd ?_lpDestroyWindow dd ?
_lpPostQuitMessage dd ?
_lpDefWindowProc dd ?
_lpLoadCursor dd ?
_lpRegisterClassEx dd ?
_lpCreateWindowEx dd ?
_lpShowWindow dd ?
_lpUpdateWindow dd ?
_lpGetMessage dd ?
_lpTranslateMessage dd ?
_lpDispatchMessage dd ?_hInstance dd ?
_hWinMain dd ?
_szClassName db 'RemoteClass',0
_szCaptionMain db 'RemoteWindow',0
_szDllUser db 'User32.dll',0
_szDestroyWindow db 'DestroyWindow',0
_szPostQuitMessage db 'PostQuitMessage',0
_szDefWindowProc db 'DefWindowProcA',0
_szLoadCursor db 'LoadCursorA',0
_szRegisterClassEx db 'RegisterClassExA',0
_szCreateWindowEx db 'CreateWindowExA',0
_szShowWindow db 'ShowWindow',0
_szUpdateWindow db 'UpdateWindow',0
_szGetMessage db 'GetMessageA',0
_szTranslateMessage db 'TranslateMessage',0
_szDispatchMessage db 'DispatchMessageA',0,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RemoteThread proc uses ebx edi esi lParamlocal @hModulecall @F@@:pop ebxsub ebx,offset @B
;********************************************************************_invoke [ebx + _lpGetModuleHandle],NULLmov [ebx + _hInstance],eaxlea eax,[ebx + offset _szDllUser]_invoke [ebx + _lpGetModuleHandle],eaxmov @hModule,eaxlea esi,[ebx + offset _szDestroyWindow]lea edi,[ebx + offset _lpDestroyWindow].while TRUE_invoke [ebx + _lpGetProcAddress],@hModule,esimov [edi],eaxadd edi,4@@:lodsbor al,aljnz @B.break .if ! byte ptr [esi].endw
;********************************************************************call _WinMainret_RemoteThread endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParamcall @F@@:pop ebxsub ebx,offset @B
;********************************************************************mov eax,uMsg.if eax == WM_CLOSE_invoke [ebx + _lpDestroyWindow],hWnd_invoke [ebx + _lpPostQuitMessage],NULL
;********************************************************************.else_invoke [ebx + _lpDefWindowProc],hWnd,uMsg,wParam,lParamret.endif
;********************************************************************xor eax,eaxret_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ZeroMemory proc _lpDest,_dwSizepush edimov edi,_lpDestmov ecx,_dwSizexor eax,eaxcldrep stosbpop ediret_ZeroMemory endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc uses ebx esi edi _lParamlocal @stWndClass:WNDCLASSEXlocal @stMsg:MSGcall @F@@:pop ebxsub ebx,offset @B
;********************************************************************invoke _ZeroMemory,addr @stWndClass,sizeof @stWndClass_invoke [ebx + _lpLoadCursor],0,IDC_ARROWmov @stWndClass.hCursor,eaxpush [ebx + _hInstance]pop @stWndClass.hInstancemov @stWndClass.cbSize,sizeof WNDCLASSEXmov @stWndClass.style,CS_HREDRAW or CS_VREDRAWlea eax,[ebx + offset _ProcWinMain]mov @stWndClass.lpfnWndProc,eaxmov @stWndClass.hbrBackground,COLOR_WINDOW + 1lea eax,[ebx + offset _szClassName]mov @stWndClass.lpszClassName,eaxlea eax,@stWndClass_invoke [ebx + _lpRegisterClassEx],eax
;********************************************************************
; 建立并显示窗口
;********************************************************************lea eax,[ebx + offset _szClassName]lea ecx,[ebx + offset _szCaptionMain]_invoke [ebx + _lpCreateWindowEx],WS_EX_CLIENTEDGE,eax,ecx,\WS_OVERLAPPEDWINDOW,\100,100,600,400,\NULL,NULL,[ebx + _hInstance],NULLmov [ebx + _hWinMain],eax_invoke [ebx + _lpShowWindow],[ebx + _hWinMain],SW_SHOWNORMAL_invoke [ebx + _lpUpdateWindow],[ebx + _hWinMain]
;********************************************************************
; 消息循环
;********************************************************************.while TRUElea eax,@stMsg_invoke [ebx + _lpGetMessage],eax,NULL,0,0.break .if eax == 0lea eax,@stMsg_invoke [ebx + _lpTranslateMessage],eaxlea eax,@stMsg_invoke [ebx + _lpDispatchMessage],eax.endwret_WinMain endp
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//createremotethread code
; RemoteThread.asm
; 向 Explorer.exe 进程中嵌入一段远程执行的代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff RemoteThread.asm
; rc RemoteThread.rc
; Link /subsystem:windows RemoteThread.obj RemoteThread.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.386.model flat, stdcalloption casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include Macro.inc
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data?
lpLoadLibrary dd ?
lpGetProcAddress dd ?
lpGetModuleHandle dd ?
dwProcessID dd ?
dwThreadID dd ?
hProcess dd ?
lpRemoteCode dd ?.const
szErrOpen db '无法打开远程线程!',0
szDesktopClass db 'Progman',0
szDesktopWindow db 'Program Manager',0
szDllKernel db 'Kernel32.dll',0
szLoadLibrary db 'LoadLibraryA',0
szGetProcAddress db 'GetProcAddress',0
szGetModuleHandle db 'GetModuleHandleA',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>include RemoteCode.asmstart:invoke GetModuleHandle,addr szDllKernelmov ebx,eaxinvoke GetProcAddress,ebx,offset szLoadLibrarymov lpLoadLibrary,eaxinvoke GetProcAddress,ebx,offset szGetProcAddressmov lpGetProcAddress,eaxinvoke GetProcAddress,ebx,offset szGetModuleHandlemov lpGetModuleHandle,eax
;********************************************************************
; 查找文件管理器窗口并获取进程ID,然后打开进程
;********************************************************************invoke FindWindow,addr szDesktopClass,addr szDesktopWindowinvoke GetWindowThreadProcessId,eax,offset dwProcessIDmov dwThreadID,eaxinvoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or \PROCESS_VM_WRITE,FALSE,dwProcessID.if eaxmov hProcess,eax
;********************************************************************
; 在进程中分配空间并将执行代码拷贝过去,然后创建一个远程线程
;********************************************************************invoke VirtualAllocEx,hProcess,NULL,REMOTE_CODE_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE.if eaxmov lpRemoteCode,eaxinvoke WriteProcessMemory,hProcess,lpRemoteCode,\offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULLinvoke WriteProcessMemory,hProcess,lpRemoteCode,\ ;远程代码及数据放在当前进程的代码段,不能修改本地的代码段offset lpLoadLibrary,sizeof dword * 3,NULL ;应该去遍历目标进程这三个函数。mov eax,lpRemoteCodeadd eax,offset _RemoteThread - offset REMOTE_CODE_STARTinvoke CreateRemoteThread,hProcess,NULL,0,eax,0,0,NULLinvoke CloseHandle,eax.endifinvoke CloseHandle,hProcess.elseinvoke MessageBox,NULL,addr szErrOpen,NULL,MB_OK or MB_ICONWARNING.endifinvoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>end start
win32 masm32 汇编学习 及 远程线程实例相关推荐
- Win32学习笔记(25)远程线程
1.线程 <1>线程是附属在进程上的执行实体,是代码的执行流程.(一个进程至少有一个线程) <2>代码必须通过线程才能执行 这里怎么理解呢?我们用代码演示一下 #include ...
- SHU汇编程序设计常见考点、易错点总结与综合实例、汇编学习资源
文章目录 SHU汇编程序设计常见考点.易错点总结与综合实例.汇编学习资源 一.常见考点 1.寻址方式 2.移位 3.乘除运算 4.加减操作 5.取址操作 6.出入栈 7.中断 8.标志位 9.常见的字 ...
- Win32汇编学习——windows汇编语法(小甲鱼教程)
Win32汇编学习--windows汇编语法(小甲鱼教程) 1)指令集 .386 语句是汇编语句的伪指令,类似指令有:.8086 . .186 ..286 ..386/.386p . .486/ ...
- Win32 远程线程
1 .386 2 .model flat,stdcall 3 option casemap:none 4 5 include Windows.inc 6 include User32.inc 7 in ...
- 远程注入利用远程线程直接注入
利用远程线程无DLL直接注入 (okwary) 小叹的学习园地 注入代码到其他进程地址空间的方法是使用WriteProcessMemory API.这次你不用编写一个独立的DLL而是直接复制你的代码到 ...
- 远程线程注入引出的问题
一.远程线程注入基本原理 远程线程注入--相信对Windows底层编程和系统安全熟悉的人并不陌生,其主要核心在于一个Windows API函数CreateRemoteThread,通过它可以在另外一个 ...
- 远程线程需要注意的问题
在远程线程内 无法 正常的 定义结构,或者叫做较大的对象. 我用 static解决了问题. 可能是定义在了静态存储区域了吧. 另外关于 远程线程不能直接使用 "InitWindow" ...
- WinAPI【远程注入】利用远程线程注入DLLDelphi版
{ WinAPI[远程注入]利用远程线程注入DLLDelphi版} (okwary) 小叹的学习园地 ( SDK文档里是这样描述的:进程是一个正在运行的程序,它拥有自己的地址空间,拥有自己的 ...
- 远程线程注入dll的一个例子,netcat.dll
远程dll示例,学习远程线程的例子 masm32 v11 免费下载 Windows环境下32位汇编语言程序设计中13章的远程注入dll的例子 说明HideDll.dll既是nc.dll(改了个名,军刀 ...
最新文章
- 成考高起专计算机统考试题,成考考试题型
- 大批量执行webservice出现“无法连接远程服务器”解决方案
- Scala入门到精通——第九节 继承与组合
- 在Visual Studio 2010 中使用菱形向导对窗口进行布局
- DELL XPS 9350 无线网卡DW1820A WIN7驱动异常解决
- 收集6 款 Java 8 自带工具,轻松分析定位 JVM 性能问题!
- mikrotikROS系统的几种安装方法
- -42%!新能源补贴退坡后 比亚迪2019年利润几乎砍半
- Tomcat8配置Https协议,Tomcat配置Https安全访问,Tomcat Https配置
- C++实现整数值转中文大写
- [转]使用SCOM 2012监控网络
- EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能
- Matlab中median函数的使用
- java学生成绩分90及格_Java基础练习:题目:利用条件运算符的嵌套来完成此题:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下 的用C表示。 - 菜鸟头头...
- MVDR最小方差无畸形相应波束形成器 Python 实现
- VisualAge使用技巧(二)
- 华为机试_HJ24 合唱队【中等】【收藏】
- git仓库中文件较多,如何拉取指定文件到本地
- Android点9图机制及在聊天气泡中的应用
- Fabric 超级账本学习【1】Fabcar网络调用Fabric-Java-SDK进行简单开发 FabCar
热门文章
- ML之DT:基于简单回归问题训练决策树(DIY数据集+七种{1~7}深度的决策树{依次进行10交叉验证})
- TF之DD:实现输出Inception模型内的某个卷积层或者所有卷积层的形状
- Dataset之IRIS:莺尾(Iris)数据集的简介、安装、使用方法之详细攻略
- Linux常用命令 积累
- GitHub如何删除一个repository(仓库)
- OpenGL学习笔记以及其它学习思考
- 多线程,线程同步,synchronized关键字的用法
- Python函数之初体验
- STL中各容器和适配器类的定义
- Javascript获取url参数值