list 可以使用ulong64吗
时间: 2023-10-04 22:09:40 浏览: 48
在C++中,`list` 是一个双向链表容器,用于存储元素。它可以存储任何类型的元素,包括 `ulong64`(无符号64位整数)类型。
可以使用 `list<ulong64>` 来声明一个存储 `ulong64` 元素的 `list` 容器,然后使用其提供的成员函数来操作和访问元素。例如:
```cpp
#include <iostream>
#include <list>
int main() {
std::list<ulong64> myList;
myList.push_back(1234567890123456);
myList.push_front(9876543210987654);
for (const auto& num : myList) {
std::cout << num << std::endl;
}
return 0;
}
```
上述示例中,我们声明了一个 `list<ulong64>` 类型的 `myList`,并使用 `push_back()` 和 `push_front()` 函数向列表中添加元素。然后,我们使用范围循环(range-based loop)遍历列表中的元素,并将其打印到控制台。
需要注意的是,`list` 是一个动态分配的链表结构,它不像连续的数组那样具有随机访问的特性。这意味着在 `list` 中访问元素的时间复杂度是 O(n),而不是 O(1)。如果需要频繁进行随机访问操作,可能更适合使用其他容器,如 `vector` 或 `deque`。
相关问题
list_entry
list_entry是一个宏定义,用于获取包含某个list_head指针的结构体的指针。该宏定义如下:
```C
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
```
其中,`ptr`是指向`list_head`的指针,`type`是包含`list_head`的结构体的类型,`member`是`list_head`在结构体中的成员名。该宏定义将`ptr`强制转换为`type`类型的结构体指针,并通过计算偏移量将`list_head`的指针转换为结构体的指针。这样就可以通过结构体指针访问到完整的结构体对象了。
举个例子,假设有以下结构体定义:
```C
typedef struct _MYDATASTRUCT {
ULONG number;
LIST_ENTRY ListEntry;
} MYDATASTRUCT, *PMYDATASTRUCT;
```
其中,`MYDATASTRUCT`是包含`LIST_ENTRY`的结构体类型。通过使用`list_entry`宏,可以方便地获取`MYDATASTRUCT`指针。
在`list_entry`宏内部,通过将`ptr`的地址减去`&((type *)0)->member`的地址,可以得到`list_head`相对于包含它的结构体起始地址的偏移量。然后将这个偏移量加上`ptr`的地址,即可得到包含`list_head`的结构体的指针。
对于`MYDATASTRUCT`来说,它的`list_head`成员是`ListEntry`,而在`list_entry`宏的使用中,`member`参数就是`ListEntry`。这样,通过调用`list_entry`宏并传入`ptr`、`MYDATASTRUCT`和`ListEntry`,就可以获取到包含`ptr`的`MYDATASTRUCT`指针了。
需要注意的是,`list_entry`宏中的0是一个虚拟的结构体指针,用于计算偏移量。实际使用时,需要将其替换为实际的结构体类型。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* [list_entry的宏定义](https://blog.csdn.net/lhf0921/article/details/5474095)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
- *2* *3* [LIST_ENTRY链表学习](https://blog.csdn.net/ilovemayverymuch/article/details/38742117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
[ .reference_list ]
通过PEB遍历进程模块(x64/wow4)
PEB(Process Environment Block)是Windows操作系统中的一个重要结构体,它包含了当前进程的环境信息。通过PEB,我们可以获取当前进程的模块信息,包括模块的基地址、模块的名称等。
在x64和wow64下,PEB结构体的定义并没有变化,但是由于x64和wow64的指针长度不同,所以在使用PEB时需要注意指针长度的问题。
以下是通过PEB遍历进程模块的代码示例:
```c++
#include <windows.h>
#include <winternl.h>
#include <iostream>
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PVOID EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID AtlThunkSListPtr;
PVOID IFEOKey;
PVOID CrossProcessFlags;
PVOID UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
PVOID ApiSetMap;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[2];
PVOID ReadOnlySharedMemoryBase;
PVOID HotpatchInformation;
PVOID ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
LARGE_INTEGER CriticalSectionTimeout;
ULONG_PTR HeapSegmentReserve;
ULONG_PTR HeapSegmentCommit;
ULONG_PTR HeapDeCommitTotalFreeThreshold;
ULONG_PTR HeapDeCommitFreeBlockThreshold;
ULONG_PTR NumberOfHeaps;
ULONG_PTR MaximumNumberOfHeaps;
PVOID ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
USHORT OSCSDVersion;
ULONG OSPlatformId;
ULONG ImageSubsystem;
ULONG ImageSubsystemMajorVersion;
ULONG ImageSubsystemMinorVersion;
ULONG_PTR ImageProcessAffinityMask;
ULONG_PTR GdiHandleBuffer[34];
PVOID PostProcessInitRoutine;
PVOID TlsExpansionBitmap;
ULONG TlsExpansionBitmapBits[32];
ULONG SessionId;
ULARGE_INTEGER AppCompatFlags;
ULARGE_INTEGER AppCompatFlagsUser;
PVOID pShimData;
PVOID AppCompatInfo;
UNICODE_STRING CSDVersion;
PVOID ActivationContextData;
PVOID ProcessAssemblyStorageMap;
PVOID SystemDefaultActivationContextData;
PVOID SystemAssemblyStorageMap;
ULONG_PTR MinimumStackCommit;
} PEB, *PPEB;
void EnumerateProcessModules(HANDLE hProcess)
{
PEB peb;
ZeroMemory(&peb, sizeof(PEB));
// 获取PEB地址
BOOL bRet = ReadProcessMemory(hProcess, &NtCurrentTeb()->ProcessEnvironmentBlock, &peb, sizeof(PEB), NULL);
if (!bRet)
{
std::cout << "ReadProcessMemory failed!" << std::endl;
return;
}
// 遍历模块列表
PPEB_LDR_DATA pLdrData = peb.LoaderData;
if (pLdrData == NULL)
{
std::cout << "LoaderData is NULL!" << std::endl;
return;
}
PLIST_ENTRY pListHead = &pLdrData->InMemoryOrderModuleList;
PLIST_ENTRY pListEntry = pListHead->Flink;
while (pListEntry != pListHead)
{
PLDR_DATA_TABLE_ENTRY pLdrEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if (pLdrEntry->DllBase != NULL)
{
// 获取模块基地址和名称
wchar_t szModule[MAX_PATH] = { 0 };
bRet = ReadProcessMemory(hProcess, pLdrEntry->FullDllName.Buffer, szModule, pLdrEntry->FullDllName.Length, NULL);
if (bRet)
{
std::wcout << L"Module Base: " << pLdrEntry->DllBase << L", Module Name: " << szModule << std::endl;
}
}
pListEntry = pListEntry->Flink;
}
}
int main(int argc, char* argv[])
{
DWORD dwProcessId = 0;
if (argc > 1)
{
dwProcessId = atoi(argv[1]);
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == NULL)
{
std::cout << "OpenProcess failed!" << std::endl;
return 0;
}
EnumerateProcessModules(hProcess);
CloseHandle(hProcess);
return 0;
}
```
需要注意的是,以上代码中使用了一些Windows内部的结构体和函数,如`UNICODE_STRING`、`LIST_ENTRY`、`NtCurrentTeb()`等,需要包含相应的头文件,并且这些结构体和函数都不是官方公开的API,可能会在未来的操作系统版本中发生变化。因此,开发者在使用这些结构体和函数时需要特别注意。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)