能力值:
( 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
被一半人生编辑
,原因:
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
.
最后于 2023-1-12 06:45
被PEDIY编辑
,原因:
|
能力值:
( LV9,RANK:140 )
|
-
-
4 楼
可能是因为notepad是64位的,你的程序是32位的,指针的问题。我测试你的代码没问题。
|
能力值:
( LV3,RANK:30 )
|
-
-
5 楼
32位进程在64位系统上运行时会有两个PEB(分别是32位和64位的),而64位进程只有PEB64。32位进程在系统调用时并不会直接进入内核,需要先在wow64子系统上做转换,然后进入内核。当32位进程调用NtQueryInformationProcess时,basicinfo的peb地址存放的是PEB32,而notepad是64位进程,没有PEB32。下面的截图可以验证这一点:
|
能力值:
( LV6,RANK:80 )
|
-
-
6 楼
一半人生
姿势不对: MyNtQueryInformationProcess = (NtQueryInformationProcessFake)GetProcAddress ...
本进程句柄应该不需要复制才对
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
3Q for 4L 5L的解答. 这台电脑是32位系统, 应该不是notepad是64位导致的. 调试时NtQuery已经返回0(成功), 且返回的PEB应该是正确的(7FFD5000), 只是process parameter显示的是图上那样“不能读取”
|
能力值:
( 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;另外涉及指针、内存应该判断下是否有效,有返回值的函数应该判断下是否成功,良好的习惯是成功的第一步。
|
能力值:
( LV3,RANK:30 )
|
-
-
9 楼
从截图上看,你直接用了pbi里的peb地址,这个地址是notepad进程的,在本进程里是无效的。在执行完如图所示的第260行后,peb变量就初始化了,里面的指针都需要使用ReadProcessMemory读取到本地再使用。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
superlover
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
... 要说代码健壮性, 那还得加一大套乱七八糟, 发代码就要直指关键, 否则弄一大堆阅帖者更没空、没心情看.
最后于 2023-1-7 11:27
被PEDIY编辑
,原因:
|
能力值:
( LV3,RANK:20 )
|
-
-
11 楼
我是用NtWow64QueryInformationProcess64实现的
最后于 2023-1-8 07:52
被kagayaki编辑
,原因:
|
能力值:
( LV3,RANK:20 )
|
-
-
12 楼
当时我看到别人做进程查看,都是用64位的进程,或同时用32位和64位的进程实现,为什么不用32位的进程来做?到自已试试用32位的进程来做,才发现自已对系统进程方面理解不够,入坑了。。。不过我当时用32位进程来做,是因为我这编译器(D7)版本不支持64位,所以只能用32位的
最后于 2023-1-8 06:48
被kagayaki编辑
,原因:
|
能力值:
( LV3,RANK:20 )
|
-
-
13 楼
还有建议你API要什么权限的就申请什么权限,不要动不动就PROCESS_ALL_ACCESS,不同系统,权限不一样,如XP和WIN7就不同
|
能力值:
( LV12,RANK:312 )
|
-
-
14 楼
黑洛
本进程句柄应该不需要复制才对
因为用的PROCESS_ALL_ACCESS权限,后面调用了Dup函数。
|
能力值:
( LV12,RANK:312 )
|
-
-
15 楼
PEDIY
为何用OpenProcess(PROCESS_ALL_ACCESS 不行.非要用复制的句柄?原理怎么讲
用ALL,要Dup下
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
这种情况下,肯定是先怀疑自己的代码问题啊
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
hixhi
这种情况下,肯定是先怀疑自己的代码问题啊[em_13]
看不见早结帖了?前面有一个真正回答正确了. 你回答错误
|
能力值:
( LV4,RANK:50 )
|
-
-
18 楼
.。。
最后于 2023-1-11 16:15
被zhangtaopy编辑
,原因:
|
|
|