RegQueryValueEx() always fill 0 in *lpData while reading REG_DWORD - c

I have a problem with the RegQueryValueEx() function
When I use it, it fill the *lpData with 0
LONG WINAPI RegQueryValueEx(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpValueName,
_Reserved_ LPDWORD lpReserved,
_Out_opt_ LPDWORD lpType,
_Out_opt_ LPBYTE lpData,
_Inout_opt_ LPDWORD lpcbData
);
Here is the code who doesn't work
#include <windows.h>
#include <stdio.h>
int main()
{
HKEY hKey = NULL;
DWORD data = 42;
DWORD type = REG_DWORD;
DWORD size = sizeof(DWORD);
LONG result;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey);
if(result == ERROR_SUCCESS)
{
result = RegQueryValueEx(hKey, "InstallDate", NULL, &type, (LPBYTE)&data, &size);
RegCloseKey(hKey);
if (result == ERROR_SUCCESS)
printf("The value is : %d\n", data);
}
return (0);
}
Output:
The value is : 0
I use Visual Studio 2012 and I'm running Win7
EDIT: Corrected line
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
Thanks to #David Heffernan

You are running a 32 bit process on 64 bit Windows. This means that you are subject to the registry redirector and so are reading out of the 32 bit view of the registry where that value really is 0. The registry redirector is mapping your key to:
HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion
Take a look in there in regedit and see that your value is 0.
You'll need to either run your code in a 64 bit process, or read from the 64 view of the registry. To do the latter, include KEY_WOW64_64KEY in the flags you pass when you open the key. More details can be found on MSDN describing how you access alternate registry keys.

Related

Writing DWORD to end of file on Windows

I am trying to figure out how to write a integer value to the end of my file. The value is size.
DWORD size = 12314432;
BOOL ret = WriteFile(hFile, size, sizeof(DWORD), NULL, NULL);
However WriteFile() requires that parameter 3 be of type LPCVOID so I am not sure how I would give it the DWORD instead.
I have tried..
unsigned char b[sizeof(DWORD)] = {0};
sprintf(b, "%d", size);
WriteFile(hFile, b, sizeof(DWORD), NULL, NULL);
However this just puts the hex value of each digit. So if size=1234 then it would write "31 32 33 44" to end of the file.
I would like the end of the file to just get the number in 4 bytes.
You provide the address of the DWORD like this:
DWORD size = 12314432;
BOOL ret = WriteFile(hFile, &size, sizeof size, NULL, NULL);
Use the ampersand to get the address of the DWORD variable.
Express your intend for the size, you want to write all of size, so say so.
You can pass (void*)&size. You do need something which has an address, like size. You can't pass an expression there. (void*) &(5*7+3) won't work.

NtCreateFile returning STATUS_OBJECT_NAME_NOT_FOUND even if the file exists in the directory

I have been trying to open an existing file using NtCreateFile, although it cannot find the file that I am looking for even if it is present in the directory I am trying to open the file in.
NtCreateFile returns the error code 0x34, aka STATUS_OBJECT_NAME_NOT_FOUND.
I triple checked if the path is in the correct format, I also made sure that both the UNICODE_STRING's Length and MaximumLength are even and not odd since it causes NtCreateFile to throw the error code 0x33 (more information here: NtOpenFile returns STATUS_OBJECT_NAME_INVALID).
I noticed though that with another .png file in the same folder it works fine, I can get a handle to the file successfully, using a different flag being FILE_DIRECTORY_FILE instead of FILE_NON_DIRECTORY_FILE.
Here's the code:
#define DLL_FILE_OPEN 1
#define DLL_NON_DIRECTORY_FILE 0x40
#define DLL_OPEN_BY_FILE_ID 0x2000
#define DLL_DIRECTORY_FILE 1
#define DLL_FILE_OPENED 1
#define DLL_SYNCRONIZE 0x00100000L
#define DLL_FILE_READ_ATTRIBUTES 0x0080
#define DLL_FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define OBJ_CASE_INSENSITIVE 0x00000040L
void main()
{
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK isb;
UNICODE_STRING NtPath;
HANDLE FileHandle;
NTSTATUS status;
ULONG FileAttributes, Flags = 0;
PVOID EaBuffer = 0;
ULONG EaLength = 0;
Flags |= DLL_NON_DIRECTORY_FILE;
Flags |= DLL_FILE_OPEN_FOR_BACKUP_INTENT;
NtPath.Buffer = (PWSTR)L"\\??\\C:\\Users\\MyUsername\\Downloads\\verifica.txt";
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer) + 1); // +1 to avoid it being an odd value.
NtPath.MaximumLength = (USHORT)(sizeof(PWSTR) + 1);
InitializeObjectAttributes(&oa, &NtPath, OBJ_CASE_INSENSITIVE, 0, 0);
status = NewNtCreateFile(&FileHandle, FILE_GENERIC_READ, &oa, &isb, NULL, NULL, FILE_SHARE_READ, DLL_FILE_OPEN, Flags, EaBuffer, EaLength);
if (status != 0)
printf("status: 0x%08X\n", status);
else
if (!FileHandle || FileHandle == INVALID_HANDLE_VALUE)
printf("Invalid handle.\n");
else
printf("file opened successfully\n");
return;
}```
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer));
Nope. That field is length in bytes.
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer)) << 1;
In additon, as you're not passing the string to something that will write to it, I recommend making NtPath.MaximumLength the same as Length.
A little warning if you continue using these APIs, file handles are opened asynchronously by default, and the IO_STATUS_BLOCK structure wants 16 byte alignment.

How should I use libpng library to convert RGBA bitmap into PNG and PNG back to RGBA bitmap

I try to use libpng library, and I encounter problem with it.
I am using CLion now, and try to include this libpng library in my project.
The problem is rather with configuration of this library to use it in my project than using this library. I think that I can make copy all *.c, *.h files from libpng into my own project in CLion, make from it static library liblibpng.a and just link against it. I even compiled liblibpng.a but when I try to use it, i.e. simple including ${path}/libpng-x.x.x/png.h there are errors and warnings in the png.h file like lack of png_uint_32 definition. Ok I can typedefine this somehow like unsigned int.
I am trying to read README.txt, and other manuals/documantations, INSTALL.txt? But there is a lot os possibilities, and I just want to include png functionalities in my project. Why there is need to install this library? I want that my app after creation in the future will be easly portable to other computers without 3rd party libraries installation needed at all.
My question is hot to easily start using this libpng, and porbably also zlib libraries in my own project in CMake, I prefer static library linking, I don't want any specific installation, etc.
I think I have a problem with this declaration as this instead of defining png_uint_32 just throw error! It is from pngconf.h
#if UINT_MAX > 4294967294
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294
typedef unsigned long int png_uint_32;
#else
# error "libpng requires an unsigned 32-bit (or more) type"
#endif
Short answer, just use lodepng. It's a lot simpler to use than libpng and it comes in a single source, so you don't have to mess about with linking and setting up include paths.
Long answer
/*
write an rgba image to a memory buffer in PNG format, without any fanciness.
Params: rgba - the rgba values
width - image width
height - image height
outsize - return for size of output buffer
Returns: pointer to allocated buffer holding png data
*/
void *makePNGBuffer(unsigned char *rgba, int width, int height, size_t *outsize)
{
int code = 0;
// FILE *fp;
png_structp png_ptr = 0;
png_infop info_ptr =0;
png_bytep row = 0;
struct mem_encode state = {0, 0};
*outsize = 0;
// Initialize write structure
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fprintf(stderr, "Could not allocate write struct\n");
code = 1;
goto finalise;
}
// Initialize info structure
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fprintf(stderr, "Could not allocate info struct\n");
code = 1;
goto finalise;
}
// Setup Exception handling
if (setjmp(png_jmpbuf(png_ptr))) {
fprintf(stderr, "Error during png creation\n");
code = 1;
goto finalise;
}
// png_init_io(png_ptr, fp);
/* if my_png_flush() is not needed, change the arg to NULL */
png_set_write_fn(png_ptr, &state, my_png_write_data, my_png_flush);
// Write header (8 bit colour depth)
png_set_IHDR(png_ptr, info_ptr, width, height,
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
// Set title
/*
if (title != NULL) {
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text(png_ptr, info_ptr, &title_text, 1);
}
*/
png_write_info(png_ptr, info_ptr);
// Allocate memory for one row (3 bytes per pixel - RGB)
row = (png_bytep) malloc(4 * width * sizeof(png_byte));
// Write image data
int x, y;
for (y=0 ; y<height ; y++) {
for (x=0 ; x<width ; x++) {
// setRGB(&(row[x*3]), buffer[y*width + x]);
row[x*4] = rgba[(y*width +x)*4];
row[x*4+1] = rgba[(y*width +x)*4+1];
row[x*4+2] = rgba[(y*width +x)*4+2];
row[x*4+3] = rgba[(y*width +x)*4+3];
}
png_write_row(png_ptr, row);
}
// End write
png_write_end(png_ptr, NULL);
finalise:
// if (fp != NULL) fclose(fp);
if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
if (row != NULL) free(row);
*outsize = state.size;
return state.buffer;
}
What is the error?
ANSI-C (aka ISO C90) requires ULONG_MAX to have a value greater than or equal to 4294967295, so obviously a comparison with 4294967294 always succeeds on an ANSI compiler, and obviously since the standard uses exactly that decimal string, a compiler which has a problem with a number one less is not an ANSI-C compiler.
John Bowler
Please try making those big integers in pngconf.h unsigned by putting a "U" at the end:
if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32;
#else
It may be that on your platform 4294967294 cannot be represented as a signed integer so the first comparison fails due to the number being undefined.

ReadProcessMemory with __int64 address

Hey guys I want to get some memory from a process that I already know with CheatEngine. I defined a region that I want to scan (0x190D186FF->0x190D1870A) but the address is too big to be stored in a simple int. That's why I use an __int64 but with that modification ReadProcessMemory doesn't seems to handle the address anymore.
When I compile I got 3 warnings for VirtualProtectEx and ReadProcessMemory: cast to pointer from integer of different size
How can I read really big address from the memory ?
int main( int argc, char *argv[] ) {
HWND hWnd;
DWORD PID;
HANDLE hProc;
__int64 address;
char mem = 0;
PDWORD oldProtect = 0;
int valid = 0;
char inputPID[4];
printf( "What is the program PID ?\n" );
fgets( inputPID, sizeof( inputPID ), stdin );
PID = (DWORD)atoi( inputPID );
hProc = OpenProcess( PROCESS_VM_READ, false, PID );
if ( !hProc ) {
printf( "Error: Couldn't open process '%i'\n", PID );
return 0;
}
for ( address = 0x190D186FF; address <= 0x190D1870A; address++ ) {
VirtualProtectEx( hProc, (PVOID)address, (SIZE_T)sizeof( address ), PAGE_READONLY, oldProtect );
valid = ReadProcessMemory( hProc, (PCVOID)address, &mem, (DWORD)sizeof( char ), NULL );
if ( valid ) {
printf( "Memory value at 0x%I64x: '%c'\n", address, mem );
}
VirtualProtectEx( hProc, (PVOID)address, (SIZE_T)sizeof( address ), (DWORD)oldProtect, NULL );
}
system( "pause" );
}
Your problem is your trying to stuff 64bit of data into 32bit variables. You need to switch your project to build in x64.
Your compiler doesn't automatically compile as x64 on a 64 bit OS. You need to change your Configuration build type to compile for x64.
There are 2 ways you can go about making this easier on yourself.
1) Compile for same process architecture as the process you're going to be interacting with, this alleviates many problems. Use uintptr_t or UINT_PTR which will resolve to the correct pointer size either 32 bit or 64 bit depending which you compile for, for all your addresses and offsets.
2) Make your own TYPEDEF like
#define TARGET_X64
#ifdef TARGET_X64
typedef unsigned __int64 addr_ptr
#else
typedef unsigned int addr_ptr
#endif
Then define TARGET_X64 when you're interacting with a x64 process. If you do it like this, and you're compiling as x32 there are certain API's that with have complications when accessing x64 processes and vice versa.
I highly recommend using the first method.

LVM_GETITEMTEXT for x32 and x64 in C

I've been trying to get the text of items in listview another process. I found an awesome tutorial on CodeProject. Thanks to this article I was able to do this on x32. But when try to run on x64, it crashes the application I'm trying to access when SendMessage is called. In the articles comments people had simliar problems because of different pointer sizes. Some people suggested using a x64 compiler which I cant use. I need my program to run on both x32/x64. One guy suggested:
I have the answer. The LVITEM
structure is wrong under 64-bit
systems. Pointers are 64-bit now, so
the text pointer has to be followed by
a dummy value, to offset the length
member correctly.
I think this would be the best solution, as I could run it for x32 and x64 with one exe. I just have no idea how to do what hes talking about. I have included my code which currently works on x32. If anyone can help me out. That would be awesoem.
LVITEMLVITEM lvi, *_lvi;
char item[512];
char *_item;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(procList, &pid);
process = OpenProcess(0x001f0fff, FALSE, pid);
_lvi = (LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), 0x1000, 4);
_item = (char*)VirtualAllocEx(process, NULL, 512, 0x1000, 4);
lvi.cchTextMax = 512;
int r, c;
for (r = 0; r < rowCount; r++)
{
for (c = 0; c < columnCount; c++)
{
lvi.iSubItem = c;
lvi.pszText =_item;
// Insert lvi into programs's memory
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
// Have program write text to in its memory where we told it to
SendMessage(procList, LVM_GETITEMTEXT, (WPARAM)r, (LPARAM)_lvi);
// Get TVITEM back from programs
ReadProcessMemory(process, _item, item, 512, NULL);
}
}
// Clean up the mess we made
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
CloseHandle(process);
I don't think you'll be able to achieve this. In a 32 bit process your pointers will be too short. I believe that VirtualAllocEx will fail when called from a 32 bit process and with a 64 bit process handle as its first parameter. I think you would see this if you added error checking to your code.
Your only solution will be to have 2 versions, x86 and x64. That should be no real trouble - usually it can be done with single source.
Sending LVM_GETITEMTEXT message from 32-bit application to 64-bit ListView is actually possible.
I was able to achieve this by using not the original LVITEM (60 bytes long) but LVITEM structure (88 bytes long) with seven 4-byte placeholders inserted between members. It works on my Win7 Pro 64-bit, though I have not tested this approach yet on other machines.
Below is the structure. This is C++, but nothing prevents us from doing the same in .NET.
typedef struct {
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
int placeholder1;
LPTSTR pszText;
int placeholder11;
int cchTextMax;
int iImage;
LPARAM lParam;
int placeholder2;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
int iGroupId;
UINT cColumns;
int placeholder3;
UINT puColumns;
int placeholder4;
#endif
#if (_WIN32_WINNT >= 0x0600)
int piColFmt;
int placeholder5;
int iGroup;
int placeholder6;
#endif
} LVITEM64, *LPLVITEM64;

Resources