I am trying to get the names of a processes handle. I iterate trough a list of all handles and try to get the name like this:
void SystemHandle::GetHandleName()
{
HANDLE hFake;
char* objectName = NULL;
if (NT_SUCCESS(DuplicateHandle(this->process, this->GetNativeHandle(), GetCurrentProcess(), &hFake, 0, FALSE, DUPLICATE_SAME_ACCESS)))
{
POBJECT_TYPE_INFORMATION typeInfo = (POBJECT_TYPE_INFORMATION)new BYTE[0x1000];
PUNICODE_STRING nameInfo = (PUNICODE_STRING)new BYTE[0x1000];
DWORD read;
NTSTATUS status = NtQueryObject(hFake, ObjectTypeInformation, typeInfo, 0x1000, &read);
std::cout << "NtQueryObject: " << status << ", Success: " << NT_SUCCESS(status) << "\n";
objectName = new char[nameInfo->Length];
if (NT_SUCCESS(status) && nameInfo->Length > 0)
{
std::cout << "nameInfo length: " << nameInfo->Length << "\n";
std::cout << "objectName size: " << sizeof(objectName) << "\n";
std::cout << "nameInfo buffer: " << sizeof(nameInfo->Buffer) << "\n";
WideToChar(objectName, nameInfo->Buffer);
strcpy_s(this->handleName, objectName);
}
delete nameInfo;
delete typeInfo;
}
if (hFake) CloseHandle(hFake);
}
void WideToChar(char* Dest, const WCHAR* Source)
{
int i = 0;
// get each char from Source and put it in Dest
while(Source[i] != '\0')
{
Dest[i] = (CHAR)Source[i];
++i;
}
Dest[i] = '\0'; // create the end
}
My problem begins at WideToChar(objectName, nameInfo->Buffer); when I get to while(Source[i] != '\0'). I will then get the following error :
Unhandled exception at 0x00406CE5 in application.
exe: 0xC0000005: Access violation reading location 0xBAADF00D.
You allocate memory for the nameInfo variable, but do not initialize it. So when you try to use it, nameInfo->Buffer contains 0xBAADF00D - Microsoft magic number for uninitialized heap memory. Then you get access violation. You also should use WideCharToMultibyte function for string conversion.
wrap
while(Source[i] != '\0')
{
Dest[i] = (CHAR)Source[i];
++i;
}
inside an if condition:
if(Source != NULL){
}
Related
i'm trying to make a little program to my university that can change values in the memory of another process. With the exact address value that the Cheat Engine give me i can do this, but not ever the value is the same then my problem is with the memory pointers. In the following image i has the every offset that i found in the pointer scan map:
I already make a program but it not work and ever gives me 299 error code, i Run it as administrator. The code is the following:
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <queue>
using namespace std;
int main() {
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
// Snapshot to list all process
HANDLE pHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (pHandlers == NULL) {
cout << "Error 1";
return 1;
}
// Listing process
if (Process32First(pHandlers, &pEntry)) {
while (Process32Next(pHandlers, &pEntry)) {
// Convert value to string
wstring wstr(pEntry.szExeFile);
string str(wstr.begin(), wstr.end());
// Check if is the process that i wan't
if (str == "Playgroundd.exe") {
MODULEENTRY32 mEntry;
mEntry.dwSize = sizeof(MODULEENTRY32);
// Snapshot to list all modules inside process
HANDLE mHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pEntry.th32ProcessID);
if (mHandlers == NULL) {
cout << "Error 2";
return 1;
}
// Usually the first process is the main module
if (Module32First(mHandlers, &mEntry)) {
// Convert the name to string
wstring wstrr(mEntry.szExePath);
string strr(wstrr.begin(), wstrr.end());
if (strr.find("Playgroundd.exe")) {
// Get the base address of module
DWORD moduleBaseAddress = (DWORD)mEntry.modBaseAddr;
// Append initial value
moduleBaseAddress += (DWORD)0x000000E8;
// Offsets defined
DWORD offsets[] = {0x88,0x98,0x90,0x20,0x10,0x48,0x904};
// Open process with the right process id
cout << "process id: " << pEntry.th32ProcessID << endl << endl;
HANDLE processHandler = OpenProcess(PROCESS_ALL_ACCESS, 0, pEntry.th32ProcessID);
if (processHandler == NULL) {
cout << "Can't open the process";
return 1;
}
// Sum offsets
for (int i = 0; i < 7;i++) {
moduleBaseAddress += offsets[i];
}
int receive = 0;
size_t bytesRead = 0;
bool resultStatus = ReadProcessMemory(processHandler,
(LPCVOID)moduleBaseAddress, &receive, sizeof(receive), &bytesRead);
cout << "result status :" << resultStatus << endl;
cout << "Received : " << receive << endl;
cout << "Bytes read : " << bytesRead << endl;
cout << "Possible error code : " << GetLastError() << endl;
}
else {
cout << "Can't find module";
return 1;
}
}
}
}
}
};
This is the output of the above program, the error code can be ignored if the result status be non-zero
result status :0
Received : 0
Bytes read : 0
Possible error code : 299
What i am doing wrong?
As pointed by the comment above, your calculation of the target address is questionable.
Your use of GetLastError is unsafe - you should call it immediately after FAILED call to ReadProcessMemory. However, in this case, cout << ... doesn't change that code, so you are OK.
According to docs
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
And this post states
ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault.
The below code can correctly read Registry values from various different keys, however whenever I try to read a value from a key under Winlogon it will either come up as "not found" or it will return a completely wrong value. The code is ran as admin, and compiled with Visual Studio 2017.
HKEY registryHandle = NULL;
int registryResult = NULL;
DWORD dataType;
TCHAR dataBuffer[1024] = {};
DWORD bufferSize = sizeof(dataBuffer);
registryResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, ®istryHandle);
if (registryResult != ERROR_SUCCESS) {
std::cout << "Error: " << registryResult << std::endl;
return false;
}
registryResult = RegQueryValueEx(registryHandle, L"LastUsedUsername", NULL, NULL, (LPBYTE)dataBuffer, &bufferSize);
if (registryResult != ERROR_SUCCESS) {
std::cout << "Error2: " << registryResult << std::endl;
return false;
}
std::cout << "Data Size: " << bufferSize << std::endl;
for (int i = 0; i < 256; i++) {
if (dataBuffer[i] == NULL) { break; }
std::cout << (char)dataBuffer[i];
}
std::cin.get();
RegCloseKey(registryHandle);
Registry value that I'm trying to read:
Below refers to Remy's suggested solution.
RegQueryValueEx Returns a buffer size of 4 with an output of 18754 17236 0 52428
You are clearly calling the Unicode version of the Registry functions, so you should be using WCHAR instead of TCHAR for your data buffer.
And you should not be truncating the characters to char at all. Use std::wcout instead of std::cout for printing out Unicode strings. And use the returned bufferSize to know how many WCHARs were actually output. Your printing loop is ignoring the bufferSize completely, so it is possible that you are actually printing out random garbage that RegQueryValueEx() did not actually intend for you to use (hence why lpcbData parameter is an in/out parameter, so you know how many bytes are actually valid).
You are also leaking the opened HKEY handle if RegQueryValueEx() fails.
Try something more like this instead:
HKEY registryHandle;
int registryResult;
registryResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, ®istryHandle);
if (registryResult != ERROR_SUCCESS) {
std::cout << "Error: " << registryResult << std::endl;
return false;
}
WCHAR dataBuffer[1024];
DWORD bufferSize = sizeof(dataBuffer);
// TODO: consider using RegGetValueW() instead, which is safer
// when it comes to reading string values from the Registry...
registryResult = RegQueryValueExW(registryHandle, L"LastUsedUsername", NULL, NULL, (LPBYTE)dataBuffer, &bufferSize);
RegCloseKey(registryHandle);
if (registryResult != ERROR_SUCCESS) {
std::cout << "Error2: " << registryResult << std::endl;
return false;
}
DWORD len = bufferSize / sizeof(WCHAR);
if ((len > 0) && (dataBuffer[len-1] == L'\0')) {
--len;
}
std::cout << "Data Byte Size: " << bufferSize << std::endl;
std::cout << "Data Character Length: " << len << std::endl;
std::wcout.write(dataBuffer, len);
std::cin.get();
return true;
That being said, on my machine, there is no LastUsedUsername value in the Winlogon key you are accessing, so getting a "not found" error is a very likely possibility. But you definately need to handle
I am writing a basic ldap query in c++ that will need to return our servers/workstations. I found this example off of Microsofts site and have changed it up a little to fit what I need.
https://msdn.microsoft.com/en-us/library/aa367016(v=vs.85).aspx
I am able to bind to our servers and run queries with no issue and dump it into a log file, but I am unable to return more than 4000 objects. Our domain is very large with subdomains, and we will need to query more than 4000. I am able to run a query against the same Domain Controller with powershell and that returns all the objects. Query I am running for testing purposes is: "(objectCategory=computer)"I would like to keep it in c++ since I will be integrating it with an already existing program.
According to: https://msdn.microsoft.com/en-us/library/aa366971(v=vs.85).aspx
I should be able to set the sizelimit to 0 and all entries should be returned (Unless my understanding on what they mean by entries is wrong). However, changing from ldap_search_s() to ldap_search_ext_s and setting a flag for LDAP_NO_LIMIT or 0 made no difference on the amount of entries returned. As of now I have been stuck trying to figure out why I can't return all entries with what I have.
Here is what I got for code.
`//New Class//
Search *s = new Search;
ULONG numReturned = 0; //No Limit
char *LdapServer = "Domain.com";
//Init ssl//
LDAP *ldap = ldap_sslinitA(LdapServer, LDAP_SSL_PORT, 1);
unsigned long version = LDAP_VERSION3;
ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, (void*)&numReturned);
//Define what attributes to return//
PCHAR pMyAttributes[2];
pMyAttributes[0] = "distinguishedName";
pMyAttributes[1] = NULL;
//Message return handle//
LDAPMessage *pMsg = NULL;
unsigned long connectSuccess = ldap_connect(ldap, NULL);
if (connectSuccess == LDAP_SUCCESS) {
std::cout << "Connection to ldap successful\n";
ldap_simple_bind(ldap, s->user, s->pw);
std::string beginSearch = "";
std::cout << "Enter your custom query:\n";
std::getline(std::cin, beginSearch);
ldap_search_ext_s(ldap, "dc=Domain,dc=com", LDAP_SCOPE_SUBTREE,
(PSTR)beginSearch.c_str(), pMyAttributes, NULL, NULL, NULL,NULL,
LDAP_NO_LIMIT, &pMsg);
ULONG numberOfEntries;
numberOfEntries = ldap_count_entries(ldap, pMsg);
if (numberOfEntries == NULL) {
std::cout << "Ldap entries returned fail with 0x" <<
connectSuccess << "\n";
}
else {
std::cout << "Entries returned: " << numberOfEntries;
LDAPMessage *pEntry = NULL;
PCHAR pEntryDN = NULL;
ULONG iCnt = 0;
char* sMsg;
BerElement *pBer = NULL;
PCHAR pAttribute = NULL;
PCHAR *ppValue = NULL;
ULONG iValue = 0;
//Loop through the entries//
for (iCnt = 0; iCnt < numberOfEntries; iCnt++) {
//Get the first/next entry//
if (!iCnt)
pEntry = ldap_first_entry(ldap, pMsg);
else
pEntry = ldap_next_entry(ldap, pEntry);
//Output status message//
sMsg = (!iCnt ? "ldap_first_entry" : "ldap_next_entry");
if (pEntry == NULL) {
std::cout << "failed with 0x" << sMsg <<
LdapGetLastError();
ldap_unbind_s(ldap);
ldap_msgfree(pMsg);
return -1;
}
else
std::cout << "Succeeded\n" << sMsg;
std::cout << "Entry Number: " << iCnt;
pAttribute = ldap_first_attribute(ldap, pEntry, &pBer);
//Session Handle, Current Entry, [out] Current BerElement
//Begin outputting the attribute names for the current object and ouput
values//
while (pAttribute != NULL) {
std::cout << "ATTR: " << pAttribute;
Log(pAttribute);
//get string values
ppValue = ldap_get_values(ldap, pEntry, pAttribute);
//Session handle, current entry, current attribute
if (ppValue == NULL)
std::cout << "\nNo Attribute value returned!\n";
else {
iValue = ldap_count_values(ppValue);
if (!iValue)
std::cout << "BAD VALUE LIST!\n";
else {
//Output the first attribute//
std::cout << ": " << *ppValue;
Log(*ppValue);
//If there are more, continuing outputting//
ULONG z;
for (z = 1; z < iValue; z++) {
std::cout << ", " << ppValue[z];
Log(ppValue[z]);
}
}
}
if (ppValue != NULL)
ldap_value_free(ppValue);
ppValue = NULL;
ldap_memfree(pAttribute);
pAttribute = ldap_next_attribute(ldap, pEntry, pBer);
std::cout << "\n";
}
if (pBer != NULL)
ber_free(pBer, 0);
pBer = NULL;
}
ldap_unbind(ldap);
ldap_msgfree(pMsg);
ldap_value_free(ppValue);
}
}
}
`
I appreciate any help or pointers. Sorry if my code is hard to read.
It's likely that the AD you're requesting has also a sizelimit set on the server.
The one you are configuring is client side but can't overwrite the server one.
If your administrator does not want to change the server sizelimit, you will have to request using paged results controls
I don't know how to implement this in C++ though
I`m struggling for the past many hours with the following problem: I try to read a file using CreateFile and ReadFile methods.
Here is the code:
char* Utils::ReadFromFile(wchar_t* path) {
HANDLE hFile = CreateFile(
path, // long pointer word string file path (16 bit UNICODE char pointer)
GENERIC_READ, // access to file
0, // share mode ( 0 - prevents others from opening/readin/etc)
NULL, // security attributes
OPEN_EXISTING, // action to take on file -- returns ERROR_FILE_NOT_FOUND
FILE_ATTRIBUTE_READONLY, // readonly and offset possibility
NULL // when opening an existing file, this parameter is ignored
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cout << "File opening failed" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
LARGE_INTEGER largeInteger;
GetFileSizeEx(hFile, &largeInteger);
LONGLONG fileSize = largeInteger.QuadPart;
if (fileSize == 0) {
std::cout << "Error when reading file size" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
cout << "File size: " << fileSize << endl;
char* bytesRead;
bytesRead = new char(fileSize);
int currentOffset = 0;
int attempts = 0;
int nBytesToBeRead = BYTES_TO_READ;
//DWORD nBytesRead = 0;
OVERLAPPED overlap{};
errno_t status;
while (currentOffset < fileSize) {
overlap.Offset = currentOffset;
if (fileSize - currentOffset < nBytesToBeRead)
nBytesToBeRead = fileSize - currentOffset;
status = ReadFile(
hFile, // file handler
bytesRead + currentOffset, // byted read from file
nBytesToBeRead, // number of bytes to read
NULL, // number of bytes read
&overlap // overlap parameter
);
if (status == 0) {
std::cout << "Error when reading file at offset: " << currentOffset << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
attempts++;
std::cout << "Attempt: " << attempts << endl;
if (attempts == 3) {
cout << "The operation could not be performed. Closing..." << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
continue;
}
else {
cout << "Read from offset: " << currentOffset;// << " -- " << overlap.InternalHigh << endl;
currentOffset += nBytesToBeRead;
if (currentOffset == fileSize) {
cout << "File reading completed" << endl;
break;
}
}
}
CloseHandle(hFile);
return bytesRead;
}
When running this method I get some weird results:
One time it worked perfectly
Very often I get Access violation reading location for currentOffset variable and overlap.InternalHigh ( I commented last one), with last method from CallStack being
msvcp140d.dll!std::locale::locale(const std::locale & _Right) Line 326 C++
Sometimes the function runs perfectly, but I get access violation reading location when trying to exit main function with last method from CallStack being
ucrtbased.dll!_CrtIsValidHeapPointer(const void * block) Line 1385 C++
I read the windows documentation thoroughly regarding the methods I use and checked the Internet for any solution I could find, but without any result. I don't understand this behaviour, getting different errors when running cod multiple times, and therefore I can`t get to a solution for this problem.
Note: The reason I am reading the file in repeated calls is not relevant. I tried reading with a single call and the result is the same.
Thank you in advance
You are allocating a single char for bytesRead, not an array of fileSize chars:
char* bytesRead;
bytesRead = new char(fileSize); // allocate a char and initialize it with fileSize value
bytesRead = new char[fileSize]; // allocate an array of fileSize chars
I have a problem where I try to compress a file's data. Everything works up to the compression call, but it isn't the compression call itself, as the segfault is thrown before it. Showing my code will make it much clearer:
std::cout << "FILENAME: ";
std::cin >> filename;
if(!fileExists(filename))
{
std::cout << "ERR: FILE NOT FOUND." << std::endl;
continue;
}
std::cout << "Compressing file data...";
writeFile(filename, zlib_compress(readFile(filename)));
std::cout << " Done." << std::endl;
At the function zlib_compress...
std::string zlib_compress(const std::string& str)
{
std::cout << "DEBUG" << std::endl;
z_stream zs; // z_stream is zlib's control structure
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, 9) != Z_OK)
std::cout << "deflateInit failed while compressing." << std::endl;
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size(); // set the z_stream's input
int ret;
char outbuffer[1073741824];
std::string outstring;
// retrieve the compressed bytes blockwise
do
{
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = deflate(&zs, Z_FINISH);
if (outstring.size() < zs.total_out)
{
// append the block to the output string
outstring.append(outbuffer, zs.total_out - outstring.size());
}
} while(ret == Z_OK);
deflateEnd(&zs);
if(ret != Z_STREAM_END) // an error occurred that was not EOF
{
std::ostringstream oss;
oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
std::cout << oss.str();
}
return outstring;
}
I know, I know, that function needs work, I just C&P'd from somewhere to try it out.
But the thing is this:
std::cout << "DEBUG" << std::endl; is never called. The compiler says that the seg fault is coming from here:
std::string zlib_compress(const std::string& str)
> {
But why...? It was working earlier. I just don't know what went wrong!
Edit: Debugger output.
#0 00000000 0x00402cbb in __chkstk_ms() (??:??)
#1 004013BE zlib_compress(str=...) (C:\Users\***\Documents\Work\Programming\Compressor\z.cpp:5)
#2 00401DDA _fu15___ZSt4cout() (C:\Users\***\Documents\Work\Programming\Compressor\main.cpp:80)
char outbuffer[1073741824];
That's too large to put on the stack
You are taking a constant reference to a string as a parameter in your zlib_compress - you need to make sure that memory is available (whatever is returned from your readfile) in your zlib_compress. It would be good if you can share the prototype of your readFile function too.