首页
社区
课程
招聘
[已结]盖茨的痿软系统真TM浪费生命,1秒解决的函数他娘地还隐藏资料,编译器也难用到死)
发表于: 2023-1-6 07:25 9237

[已结]盖茨的痿软系统真TM浪费生命,1秒解决的函数他娘地还隐藏资料,编译器也难用到死)

2023-1-6 07:25
9237
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int _tmain(int argc, TCHAR* argv[])
{
    HMODULE Hntdll = GetModuleHandleA("ntdll.dll");
    PROCESS_BASIC_INFORMATION pbi = {0};
    NtQueryInformationProcess pfn_NtQueryInformationProcess = (NtQueryInformationProcess)GetProcAddress(Hntdll, "NtQueryInformationProcess");
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 3576);//记事本进程
    NTSTATUS ret = pfn_NtQueryInformationProcess(hProcess,
                                ProcessBasicInformation,
                                &pbi,
                                sizeof(pbi),
                                NULL);
    PEB peb = {0};
    RTL_USER_PROCESS_PARAMETERS para = {0};
    ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(PEB), NULL);
    ReadProcessMemory(hProcess, peb.ProcessParameters, &para, sizeof(para), NULL);
    //*****暂时到这里*****//
    return 0;
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-1-8 20:34 被PEDIY编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (17)
雪    币: 2157
活跃值: (12639)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
2

姿势不对:

		MyNtQueryInformationProcess = (NtQueryInformationProcessFake)GetProcAddress(hm, "NtQueryInformationProcess");
		if (DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hNewDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
		{
			PROCESS_BASIC_INFORMATION pbi;
			const NTSTATUS nRet = MyNtQueryInformationProcess(hNewDup, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
			if (BCRYPT_SUCCESS(nRet)) {
				if (ReadProcessMemory(hNewDup, pbi.PebBaseAddress, &peb, sizeof(PEB), 0))
				{
					if (ReadProcessMemory(hNewDup, peb.ProcessParameters, &rups, sizeof(RTL_USER_PROCESS_PARAMETERS), 0))
					{
						WCHAR* buffer = new WCHAR[rups.CommandLine.Length + 1];
						ZeroMemory(buffer, (rups.CommandLine.Length + 1) * sizeof(WCHAR));
						ReadProcessMemory(hNewDup, rups.CommandLine.Buffer, buffer, rups.CommandLine.Length, 0);
						sProcessCmdline = CodeTool::WStr2Str(buffer);
						delete[] buffer;
					}
				}
			}
			CloseHandle(hNewDup);
		}


最后于 2023-1-6 09:22 被一半人生编辑 ,原因:
2023-1-6 09:22
1
雪    币: 1825
活跃值: (5354)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3

    .

最后于 2023-1-12 06:45 被PEDIY编辑 ,原因:
2023-1-6 16:05
1
雪    币: 3760
活跃值: (5921)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
4

可能是因为notepad是64位的,你的程序是32位的,指针的问题。我测试你的代码没问题。


2023-1-6 17:55
1
雪    币: 4154
活跃值: (1535)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5

32位进程在64位系统上运行时会有两个PEB(分别是32位和64位的),而64位进程只有PEB64。32位进程在系统调用时并不会直接进入内核,需要先在wow64子系统上做转换,然后进入内核。当32位进程调用NtQueryInformationProcess时,basicinfo的peb地址存放的是PEB32,而notepad是64位进程,没有PEB32。下面的截图可以验证这一点:

2023-1-6 23:14
1
雪    币: 6124
活跃值: (4661)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
6
一半人生 姿势不对: MyNtQueryInformationProcess = (NtQueryInformationProcessFake)GetProcAddress ...
本进程句柄应该不需要复制才对
2023-1-7 01:11
0
雪    币: 1825
活跃值: (5354)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7

3Q for 4L 5L的解答. 这台电脑是32位系统, 应该不是notepad是64位导致的. 调试时NtQuery已经返回0(成功), 且返回的PEB应该是正确的(7FFD5000), 只是process parameter显示的是图上那样“不能读取”

2023-1-7 07:37
0
雪    币: 10248
活跃值: (4421)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

// PROCESS_BASIC_INFORMATION for pure 32 and 64-bit processes
typedef struct _PROCESS_BASIC_INFORMATION
{
    PVOID Reserved1;
    PVOID PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

// PROCESS_BASIC_INFORMATION for 32-bit process on WOW64
// The definition is quite funky, as we just lazily doubled sizes to match offsets...
typedef struct _PROCESS_BASIC_INFORMATION_WOW64
{
    PVOID Reserved1[2];
    PVOID64 PebBaseAddress;
    PVOID Reserved2[4];
    ULONG_PTR UniqueProcessId[2];
    PVOID Reserved3[2];
} PROCESS_BASIC_INFORMATION_WOW64;

typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

typedef struct _UNICODE_STRING_WOW64
{
    USHORT Length;
    USHORT MaximumLength;
    PVOID64 Buffer;
} UNICODE_STRING_WOW64;



wchar_t *GetProcessPebCommandLine( DWORD dwProcessId )
{
    NTSTATUS status;
    SYSTEM_INFO si;
    BOOL wow64;
    HANDLE hProcess = NULL;
    wchar_t *pCmdLine = NULL;
    PBYTE peb = NULL;
    PBYTE pUserProcessParameters = NULL;
    do
    {
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
        if ( hProcess == NULL )
        {
            assert(FALSE);
            break;
        }
        GetNativeSystemInfo( &si );
        IsWow64Process( GetCurrentProcess(), &wow64 );
        DWORD ProcessParametersOffset = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? 0x20 : 0x10;
        DWORD CommandLineOffset = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? 0x70 : 0x40;
        DWORD pebSize = ProcessParametersOffset + 8;
        DWORD ppSize = CommandLineOffset + 16;
        peb = ( PBYTE )malloc ( pebSize * 2 );
        pUserProcessParameters = ( PBYTE )malloc ( ppSize * 2 );
        if ( peb == NULL || pUserProcessParameters == NULL )
        {
            assert( FALSE );
            break;
        }
        ZeroMemory( pUserProcessParameters, ppSize );
        ZeroMemory( peb, pebSize );
        if ( wow64 )
        {
            PROCESS_BASIC_INFORMATION_WOW64 pbi;
            ZeroMemory( &pbi, sizeof( pbi ) );
            typedef NTSTATUS( __stdcall * fnNtWow64QueryInformationProcess64 )( HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength );
            static fnNtWow64QueryInformationProcess64 pNtWow64QueryInformationProcess64 = ( fnNtWow64QueryInformationProcess64 )GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "NtWow64QueryInformationProcess64" );
            typedef NTSTATUS( __stdcall * fnNtWow64ReadVirtualMemory64 )( HANDLE ProcessHandle, PVOID64 BaseAddress, PVOID Buffer, ULONG64 Size, PULONG64 NumberOfBytesRead );
            static fnNtWow64ReadVirtualMemory64 pfnWow64ReadVirtualMemory64 = ( fnNtWow64ReadVirtualMemory64 )GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "NtWow64ReadVirtualMemory64" );
            if ( pNtWow64QueryInformationProcess64 == NULL || pfnWow64ReadVirtualMemory64 == NULL )
            {
                assert( FALSE );
                break;
            }
            status = pNtWow64QueryInformationProcess64( hProcess, 0, &pbi, sizeof( pbi ), NULL );
            if ( !NT_SUCCESS( status ) )
            {
                assert( FALSE );
                break;
            }
            status = pfnWow64ReadVirtualMemory64( hProcess, pbi.PebBaseAddress, peb, pebSize, NULL );
            if ( !NT_SUCCESS( status ) )
            {
                assert( FALSE );
                break;
            }
            // read ProcessParameters from 64-bit address space
            PBYTE *parameters = ( PBYTE * ) * ( LPVOID * )( peb + ProcessParametersOffset ); // address in remote process adress space
            status = pfnWow64ReadVirtualMemory64( hProcess, parameters, pUserProcessParameters, ppSize, NULL );
            if ( !NT_SUCCESS( status ) )
            {
                assert(FALSE);
                break;
            }
            // read CommandLine
            UNICODE_STRING_WOW64 *pCommandLine = ( UNICODE_STRING_WOW64 * )( pUserProcessParameters + CommandLineOffset );
            pCmdLine = ( PWSTR )malloc( pCommandLine->MaximumLength * 2 );
            status = pfnWow64ReadVirtualMemory64( hProcess, pCommandLine->Buffer, pCmdLine, pCommandLine->MaximumLength, NULL );
            if ( !NT_SUCCESS( status ) )
            {
                assert( FALSE );
                break;
            }
        }
        else
        {
            //我们在32位操作系统中以32位进程运行,或者在64位操作系统中以64位进程运行
            PROCESS_BASIC_INFORMATION pbi;
            ZeroMemory( &pbi, sizeof( pbi ) );
            // get process information
            typedef NTSTATUS( __stdcall * fnZwQueryInformationProcess )( HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength );
            static  fnZwQueryInformationProcess pZwQueryInformationProcess = ( fnZwQueryInformationProcess )GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "ZwQueryInformationProcess" );
            if ( pZwQueryInformationProcess == NULL )
            {
                assert( FALSE );
                break;
            }
            status = pZwQueryInformationProcess( hProcess, 0, &pbi, sizeof( pbi ), NULL );
            if ( !NT_SUCCESS( status ) )
            {
                assert( FALSE );
                break;
            }
            // read PEB
            if ( !ReadProcessMemory( hProcess, pbi.PebBaseAddress, peb, pebSize, NULL ) )
            {
                assert(FALSE);
                break;
            }
            // read ProcessParameters
            PBYTE *parameters = ( PBYTE * ) * ( LPVOID * )( peb + ProcessParametersOffset ); // address in remote process adress space
            if ( !ReadProcessMemory( hProcess, parameters, pUserProcessParameters, ppSize, NULL ) )
            {
                assert( FALSE );
                break;
            }
            // read CommandLine
            UNICODE_STRING *pCommandLine = ( UNICODE_STRING * )( pUserProcessParameters + CommandLineOffset );
            pCmdLine = ( PWSTR )malloc( pCommandLine->MaximumLength * 2 );
            if ( pCmdLine == NULL )
            {
                assert( FALSE );
                break;
            }
            ZeroMemory( pCmdLine, pCommandLine->MaximumLength );
            if ( !ReadProcessMemory( hProcess, pCommandLine->Buffer, pCmdLine, pCommandLine->MaximumLength, NULL ) )
            {
                assert( FALSE );
                break;
            }
        }
    } while ( FALSE );
    SafeFreeBuffer( pUserProcessParameters );
    SafeFreeBuffer( peb );
    SafeCloseHandle( hProcess );
    return pCmdLine;
}

这个是能用的,兼容32位64位,GetProcessPebCommandLine需要自己释放内存。楼主的代码应该是偏移的问题,也就是ProcessParametersOffset和CommandLineOffset;另外涉及指针、内存应该判断下是否有效,有返回值的函数应该判断下是否成功,良好的习惯是成功的第一步。

2023-1-7 09:16
1
雪    币: 4154
活跃值: (1535)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9

从截图上看,你直接用了pbi里的peb地址,这个地址是notepad进程的,在本进程里是无效的。在执行完如图所示的第260行后,peb变量就初始化了,里面的指针都需要使用ReadProcessMemory读取到本地再使用。

2023-1-7 09:20
1
雪    币: 1825
活跃值: (5354)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
superlover #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) ...

要说代码健壮性, 那还得加一大套乱七八糟, 发代码就要直指关键, 否则弄一大堆阅帖者更没空、没心情看. 

最后于 2023-1-7 11:27 被PEDIY编辑 ,原因:
2023-1-7 11:23
0
雪    币: 1316
活跃值: (5174)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11

我是用NtWow64QueryInformationProcess64实现的

最后于 2023-1-8 07:52 被kagayaki编辑 ,原因:
2023-1-8 06:31
0
雪    币: 1316
活跃值: (5174)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12

当时我看到别人做进程查看,都是用64位的进程,或同时用32位和64位的进程实现,为什么不用32位的进程来做?到自已试试用32位的进程来做,才发现自已对系统进程方面理解不够,入坑了。。。不过我当时用32位进程来做,是因为我这编译器(D7)版本不支持64位,所以只能用32位的

最后于 2023-1-8 06:48 被kagayaki编辑 ,原因:
2023-1-8 06:44
0
雪    币: 1316
活跃值: (5174)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
还有建议你API要什么权限的就申请什么权限,不要动不动就PROCESS_ALL_ACCESS,不同系统,权限不一样,如XP和WIN7就不同
2023-1-8 07:04
0
雪    币: 2157
活跃值: (12639)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
14
黑洛 本进程句柄应该不需要复制才对
因为用的PROCESS_ALL_ACCESS权限,后面调用了Dup函数。
2023-1-8 08:27
0
雪    币: 2157
活跃值: (12639)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
15
PEDIY 为何用OpenProcess(PROCESS_ALL_ACCESS 不行.非要用复制的句柄?原理怎么讲
用ALL,要Dup下
2023-1-8 08:28
0
雪    币: 73
活跃值: (923)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这种情况下,肯定是先怀疑自己的代码问题啊
2023-1-10 16:19
0
雪    币: 1825
活跃值: (5354)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
hixhi 这种情况下,肯定是先怀疑自己的代码问题啊[em_13]

看不见早结帖了?前面有一个真正回答正确了. 你回答错误

2023-1-10 18:52
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18

.。。

最后于 2023-1-11 16:15 被zhangtaopy编辑 ,原因:
2023-1-11 16:09
0
游客
登录 | 注册 方可回帖
返回
//