"门“ 指向某个优先级高的程序所规定的入口点,所有优先级低的程序调用优先级高的程序只能通过门重定向
门:中断门,自陷门,任务门。

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 汇编学习 及 远程线程实例相关推荐

  1. Win32学习笔记(25)远程线程

    1.线程 <1>线程是附属在进程上的执行实体,是代码的执行流程.(一个进程至少有一个线程) <2>代码必须通过线程才能执行 这里怎么理解呢?我们用代码演示一下 #include ...

  2. SHU汇编程序设计常见考点、易错点总结与综合实例、汇编学习资源

    文章目录 SHU汇编程序设计常见考点.易错点总结与综合实例.汇编学习资源 一.常见考点 1.寻址方式 2.移位 3.乘除运算 4.加减操作 5.取址操作 6.出入栈 7.中断 8.标志位 9.常见的字 ...

  3. Win32汇编学习——windows汇编语法(小甲鱼教程)

    Win32汇编学习--windows汇编语法(小甲鱼教程) 1)指令集 .386 语句是汇编语句的伪指令,类似指令有:.8086 . .186  ..286  ..386/.386p  . .486/ ...

  4. Win32 远程线程

    1 .386 2 .model flat,stdcall 3 option casemap:none 4 5 include Windows.inc 6 include User32.inc 7 in ...

  5. 远程注入利用远程线程直接注入

    利用远程线程无DLL直接注入 (okwary) 小叹的学习园地 注入代码到其他进程地址空间的方法是使用WriteProcessMemory API.这次你不用编写一个独立的DLL而是直接复制你的代码到 ...

  6. 远程线程注入引出的问题

    一.远程线程注入基本原理 远程线程注入--相信对Windows底层编程和系统安全熟悉的人并不陌生,其主要核心在于一个Windows API函数CreateRemoteThread,通过它可以在另外一个 ...

  7. 远程线程需要注意的问题

    在远程线程内 无法 正常的 定义结构,或者叫做较大的对象. 我用 static解决了问题. 可能是定义在了静态存储区域了吧. 另外关于 远程线程不能直接使用 "InitWindow" ...

  8. WinAPI【远程注入】利用远程线程注入DLLDelphi版

    { WinAPI[远程注入]利用远程线程注入DLLDelphi版} (okwary) 小叹的学习园地 ( SDK文档里是这样描述的:进程是一个正在运行的程序,它拥有自己的地址空间,拥有自己的 ...

  9. 远程线程注入dll的一个例子,netcat.dll

    远程dll示例,学习远程线程的例子 masm32 v11 免费下载 Windows环境下32位汇编语言程序设计中13章的远程注入dll的例子 说明HideDll.dll既是nc.dll(改了个名,军刀 ...

最新文章

  1. 成考高起专计算机统考试题,成考考试题型
  2. 大批量执行webservice出现“无法连接远程服务器”解决方案
  3. Scala入门到精通——第九节 继承与组合
  4. 在Visual Studio 2010 中使用菱形向导对窗口进行布局
  5. DELL XPS 9350 无线网卡DW1820A WIN7驱动异常解决
  6. 收集6 款 Java 8 自带工具,轻松分析定位 JVM 性能问题!
  7. mikrotikROS系统的几种安装方法
  8. -42%!新能源补贴退坡后 比亚迪2019年利润几乎砍半
  9. Tomcat8配置Https协议,Tomcat配置Https安全访问,Tomcat Https配置
  10. C++实现整数值转中文大写
  11. [转]使用SCOM 2012监控网络
  12. EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能
  13. Matlab中median函数的使用
  14. java学生成绩分90及格_Java基础练习:题目:利用条件运算符的嵌套来完成此题:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下 的用C表示。 - 菜鸟头头...
  15. MVDR最小方差无畸形相应波束形成器 Python 实现
  16. VisualAge使用技巧(二)
  17. 华为机试_HJ24 合唱队【中等】【收藏】
  18. git仓库中文件较多,如何拉取指定文件到本地
  19. Android点9图机制及在聊天气泡中的应用
  20. Fabric 超级账本学习【1】Fabcar网络调用Fabric-Java-SDK进行简单开发 FabCar

热门文章

  1. ML之DT:基于简单回归问题训练决策树(DIY数据集+七种{1~7}深度的决策树{依次进行10交叉验证})
  2. TF之DD:实现输出Inception模型内的某个卷积层或者所有卷积层的形状
  3. Dataset之IRIS:莺尾(Iris)数据集的简介、安装、使用方法之详细攻略
  4. Linux常用命令 积累
  5. GitHub如何删除一个repository(仓库)
  6. OpenGL学习笔记以及其它学习思考
  7. 多线程,线程同步,synchronized关键字的用法
  8. Python函数之初体验
  9. STL中各容器和适配器类的定义
  10. Javascript获取url参数值