Making a WCHAR null terminated - visual-c++

I've got this
WCHAR fileName[1];
as a returned value from a function (it's a sys 32 function so I am not able to change the returned type). I need to make fileName to be null terminated so I am trying to append '\0' to it, but nothing seems to work.
Once I get a null terminated WCHAR I will need to pass it to another sys 32 function so I need it to stay as WCHAR.
Could anyone give me any suggestion please?
================================================
Thanks a lot for all your help. Looks like my problem has to do with more than missing a null terminated string.
//This works:
WCHAR szPath1[50] = L"\\Invalid2.txt.txt";
dwResult = FbwfCommitFile(szDrive, pPath1); //Successful
//This does not:
std::wstring l_fn(L"\\");
//Because Cache_detail->fileName is \Invalid2.txt.txt and I need two
l_fn.append(Cache_detail->fileName);
l_fn += L""; //To ensure null terminated
fprintf(output, "l_fn.c_str: %ls\n", l_fn.c_str()); //Prints "\\Invalid2.txt.txt"
iCommitErr = FbwfCommitFile(L"C:", (WCHAR*)l_fn.c_str()); //Unsuccessful
//Then when I do a comparison on these two they are unequal.
int iCompareResult = l_fn.compare(pPath1); // returns -1
So I need to figure out how these two ended up to be different.
Thanks a lot!

Since you mentioned fbwffindfirst/fbwffindnext in a comment, you're talking about the file name returned in FbwfCacheDetail. So from the fileNameLength field you know length for the fileName in bytes. The length of fileName in WCHAR's is fileNameLength/sizeof(WCHAR). So the simple answer is that you can set
fileName[fileNameLength/sizeof(WCHAR)+1] = L'\0'
Now this is important you need to make sure that the buffer you send for the cacheDetail parameter into fbwffindfirst/fbwffindnext is sizeof(WCHAR) bytes larger than you need, the above code snippet may run outside the bounds of your array. So for the size parameter of fbwffindfirst/fbwffindnext pass in the buffer size - sizeof(WCHAR).
For example this:
// *** Caution: This example has no error checking, nor has it been compiled ***
ULONG error;
ULONG size;
FbwfCacheDetail *cacheDetail;
// Make an intial call to find how big of a buffer we need
size = 0;
error = FbwfFindFirst(volume, NULL, &size);
if (error == ERROR_MORE_DATA) {
// Allocate more than we need
cacheDetail = (FbwfCacheDetail*)malloc(size + sizeof(WCHAR));
// Don't tell this call about the bytes we allocated for the null
error = FbwfFindFirstFile(volume, cacheDetail, &size);
cacheDetail->fileName[cacheDetail->fileNameLength/sizeof(WCHAR)+1] = L"\0";
// ... Use fileName as a null terminated string ...
// Have to free what we allocate
free(cacheDetail);
}
Of course you'll have to change a good bit to fit in with your code (plus you'll have to call fbwffindnext as well)
If you are interested in why the FbwfCacheDetail struct ends with a WCHAR[1] field, see this blog post. It's a pretty common pattern in the Windows API.

Use L'\0', not '\0'.

As each character of a WCHAR is 16-bit in size, you should perhaps append \0\0 to it, but I'm not sure if this works. By the way, WCHAR fileName[1]; is creating a WCHAR of length 1, perhaps you want something like WCHAR fileName[1024]; instead.

WCHAR fileName[1]; is an array of 1 character, so if null terminated it will contain only the null terminator L'\0'.
Which API function are you calling?
Edited
The fileName member in FbwfCacheDetail is only 1 character which is a common technique used when the length of the array is unknown and the member is the last member in a structure. As you have likely already noticed if your allocated buffer is is only sizeof (FbwfCacheDetail) long then FbwfFindFirst returns ERROR_NOT_ENOUGH_MEMORY.
So if I understand, what you desire to do it output the non NULL terminated filename using fprintf. This can be done as follows
fprintf (outputfile, L"%.*ls", cacheDetail.fileNameLength, cacheDetail.fileName);
This will print only the first fileNameLength characters of fileName.
An alternative approach would be to append a NULL terminator to the end of fileName. First you'll need to ensure that the buffer is long enough which can be done by subtracting sizeof (WCHAR) from the size argument you pass to FbwfFindFirst. So if you allocate a buffer of 1000 bytes, you'll pass 998 to FbwfFindFirst, reserving the last two bytes in the buffer for your own use. Then to add the NULL terminator and output the file name use
cacheDetail.fileName[cacheDetail.fileNameLength] = L'\0';
fprintf (outputfile, L"%ls", cacheDetail.fileName);

Related

How to get the location in the compressed data - zlib

When I save the 'state of uncompression', I also need to save:
"location in the compressed data, which is both a byte offset and bit offset within that byte".
After a reboot, along with inflateSetDictionary(), I call inflatePrime() as below, "to feed the bits from the byte at the compressed data offset".
inflatePrime ( , streamBits, streamCurrentPos)
Both APIs return Z_OK, but params to inflatePrime(), I am bit uncertain.
This is how I gathered them:
typedef struct state_of_uncompression
{
uInt streamCurrentPos; // Missing this, tried the output from unzGetCurrentFileZStreamPos64()
int streamBits; // from : stream.data_type, after clearing bits 8,7,6: stream.data_type & (~0x1C0)
Byte dictionary_buf[32768]; // from : inflateGetDictionary()
uInt dictLength; // from : inflateGetDictionary();
uint64_t output_wrt_offset // got this already.
} uncompression_state_info;
So after the reboot, the plan is to recontinue the uncompression, but inflate() returns Z_STREAM_END inside unzReadCurrentFile(), as if, inflate() doesn't know where to restart from.
Thanks appreciate any feedback.
The third argument to inflatePrime() is not a position. It is the actual bits to insert, which you need to get from the compressed data. You use fseek() or lseek() to go to the byte offset in the file, where you saved that offset as part of your entry point information. You get that byte, which advances the file pointer to the next byte, and shift down by the number of bits you are not providing, i.e. 8 minus the second argument. That's the third argument. The second argument is always in 1..7. If there are no bits to insert, then you don't call inflatePrime(), and just leave the file pointer where it is to begin inflating.
The position in your state should be a 64-bit value, not a 32-bit value as you currently have it.

How can I get the value of a registry key in c++ without an access violation?

Hey I'm new to C++ and I am trying to find out if a specified registry index exists. I have to check multiple locations due to the possibility of the software being run on a 64bit machine and being under the WOW6432Node key instead of the usual position. When RegQueryValueExA (using visual c++ 6.0 on xp so I can't use a newer function) is run it should return a Boolean of true if the key exists, (I'll deal with getting the value of the key later). However on run it generates access violation 0xc00005. Any ideas whats gone wrong?
bool FindAndRemoveUninstall(string path){
bool result;
result = RegQueryValueExA(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC"), NULL, NULL, NULL, (unsigned long *)MAX_PATH);
if (result= ERROR_SUCCESS){
cout <<" is a 32 bit program\n";
//path= Value in key
}
result = RegQueryValueEx(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC"), NULL, NULL, NULL, (unsigned long *)MAX_PATH);
if (result= ERROR_SUCCESS){
cout << " is 64 bit program\n";
//path= Value in key
}
return true;
}
You have multiple problems.
The last parameter to RegQueryValueExA is documented as
lpcbData [in, out, optional]
A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter,
But you are not passing a pointer to a variable. You are passing (unsigned long *)MAX_PATH, which is a garbage pointer. When the operating system tries to store the result into the pointer, it takes an access violation. You need to pass a pointer to a variable, like the documentation says.
The next problem is that you are calling the A function (explicit ANSI) but using the TEXT macro (adaptive character set). Make up your mind which model you are using (ANSI or adaptive) and choose one model or the other. Let's assume you explicit ANSI.
The next problem is that you didn't specify an output buffer, so you don't actually retrieve the path.
Another problem is that the RegQueryValueExA function does not return a bool; it returns an error code.
Yet another problem is that your if test contains an assignment, so it does not actually test anything.
Another problem is that you didn't specify a way for the function to return the path to the caller. Let's assume you want the result to be returned in the path parameter.
Yet another problem is that you have the 32-bit and 64-bit cases reversed.
Also, you are using '\n' instead of std::endl.
The eight problem is that your function returns true even if it didn't do anything.
And the ninth problem is that the function says FindAndRemove, and it finds, but doesn't remove.
bool FindUninstall(string& path){ // parameter passed by reference, fix function name
LONG result; // change variable type
char buffer[MAX_PATH]; // provide an output buffer
DWORD bufferSize = MAX_PATH; // and a variable to specify the buffer size / receive the data size
result = RegQueryValueExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC", NULL, NULL, (LPBYTE)buffer, &bufferSize); // remove TEXT macro, pass the buffer and buffer size
if (result== ERROR_SUCCESS){ // fix comparison
cout <<" is a 64 bit program" << std::endl; // fix message
path = buffer;
return true; // stop once we have an answer
}
buffersize = MAX_PATH; // reset for next query
result = RegQueryValueEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ABC", NULL, NULL, (LPBYTE)buffer, &bufferSize); // remove TEXT macro, pass the buffer and buffer size
if (result== ERROR_SUCCESS){ // fix comparison
cout << " is 32 bit program" << std::endl; // fix message
path = buffer;
return true; // stop once we have an answer
}
return false; // nothing found
}
Since you are new to C++, I would recommend that you get some experience with C++ doing simpler projects before diving into more complicated things like this.

fuse: Setting offsets for the filler function in readdir

I am implementing a virtual filesystem using the fuse, and need some understanding regarding the offset parameter in readdir.
Earlier we were ignoring the offset and passing 0 in the filler function, in which case the kernel should take care.
Our filesystem database, is storing: directory name, filelength, inode number and parent inode number.
How do i calculate get the offset?
Then is the offset of each components, equal to their size sorted in incremental form of their inode number? What happens is there is a directory inside a directory, is the offset in that case equal to the sum of the files inside?
Example: in case the dir listing is - a.txt b.txt c.txt
And inode number of a.txt=3, b.txt=5, c.txt=7
Offset of a.txt= directory offset
Offset of b.txt=dir offset + size of a.txt
Offset of c.txt=dir offset + size of b.txt
Is the above assumption correct?
P.S: Here are the callbacks of fuse
The selected answer is not correct
Despite the lack of upvotes on this answer, this is the correct answer. Cracking into the format of the void buffer should be discouraged, and that's the intent behind declaring such things void in C code - you shouldn't write code that assumes knowledge of the format of the data behind void pointers, use whatever API is provided properly instead.
The code below is very simple and straightforward, as it should be. No knowledge of the format of the Fuse buffer is required.
Fictitious API
This is a contrived example of what some device's API could look
like. This is not part of Fuse.
// get_some_file_names() -
// returns a struct with buffers holding the names of files.
// PARAMETERS
// * path - A path of some sort that the fictitious device groks.
// * offset - Where in the list of file names to start.
// RETURNS
// * A name_list, it has some char buffers holding the file names
// and a couple other auxiliary vars.
//
name_list *get_some_file_names(char *path, size_t offset);
Listing the files in parts
Here's a Fuse callback that can be registered with the Fuse system to
list the filenames provided by get_some_file_names(). It's arbitrarily named readdir_callback() so its purpose is obvious.
int readdir_callback( char *path,
void *buf, // This is meant to be "opaque".
fuse_fill_dir_t *filler, // filler takes care of buf.
off_t off, // Last value given to filler.
struct fuse_file_info *fi )
{
// Call the fictitious API to get a list of file names.
name_list *list = get_some_file_names(path, off);
for (int i = 0; i < list->length; i++)
{
// Feed the file names to filler() one at a time.
if (filler(buf, list->names[i], NULL, off + i + 1))
{
break; // filler() returned 1, requesting a break.
}
incr_num_files_listed(list);
}
if (all_files_listed(list))
{
return 1; // Tell Fuse we're done.
}
return 0;
}
The off (offset) value is not used by the filler function to fill its opaque buffer, buf. The off value is, however, meaningful to the callback as an offset base as it provides file names to filler(). Whatever value was last passed to filler() is what gets passed back to readdir_callback() on its next invocation. filler()
itself only cares whether the off value is 0 or not-0.
Indicating "I'm done listing!" to Fuse
To signal to the Fuse system that your readdir_callback() is done listing file names in parts (when the last of the list of names has been given to filler()), simply return 1 from it.
How off Is Used
The off, offset, parameter should be non-0 to perform the partial listings. That's its only requirement as far as filler() is concerned. If off is 0, that indicates to Fuse that you're going to do a full listing in one shot (see below).
Although filler() doesn't care what the off value is beyond it being non-0, the value can still be meaningfully used. The code above is using the index of the next item in its own file list as its value. Fuse will keep passing the last off value it received back to the read dir callback on each invocation until the listing is complete (when readdir_callback() returns 1).
Listing the files all at once
int readdir_callback( char *path,
void *buf,
fuse_fill_dir_t *filler,
off_t off,
struct fuse_file_info *fi )
{
name_list *list = get_all_file_names(path);
for (int i = 0; i < list->length; i++)
{
filler(buf, list->names[i], NULL, 0);
}
return 0;
}
Listing all the files in one shot, as above, is simpler - but not by much. Note that off is 0 for the full listing. One may wonder, 'why even bother with the first approach of reading the folder contents in parts?'
The in-parts strategy is useful where a set number of buffers for file names is allocated, and the number of files within folders may exceed this number. For instance, the implementation of name_list above may only have 8 allocated buffers (char names[8][256]). Also, buf may fill up and filler() start returning 1 if too many names are given at once. The first approach avoids this.
The offset passed to the filler function is the offset of the next item in the directory. You can have the entries in the directory in any order you want. If you don't want to return an entire directory at once, you need to use the offset to determine what gets asked for and stored. The order of items in the directory is up to you, and doesn't matter what order the names or inodes or anything else is.
Specifically, in the readdir call, you are passed an offset. You want to start calling the filler function with entries that will be at this callback or later. In the simplest case, the length of each entry is 24 bytes + strlen(name of entry), rounded up to the nearest multiple of 8 bytes. However, see the fuse source code at http://sourceforge.net/projects/fuse/ for when this might not be the case.
I have a simple example, where I have a loop (pseudo c-code) in my readdir function:
int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
(a bunch of prep work has been omitted)
struct stat st;
int off, nextoff=0, lenentry, i;
char namebuf[(long enough for any one name)];
for (i=0; i<NumDirectoryEntries; i++)
{
(fill st with the stat information, including inode, etc.)
(fill namebuf with the name of the directory entry)
lenentry = ((24+strlen(namebuf)+7)&~7);
off = nextoff; /* offset of this entry */
nextoff += lenentry;
/* Skip this entry if we weren't asked for it */
if (off<offset)
continue;
/* Add this to our response until we are asked to stop */
if (filler(buf, namebuf, &st, nextoff))
break;
}
/* All done because we were asked to stop or because we finished */
return 0;
}
I tested this within my own code (I had never used the offset before), and it works fine.

Format string vulnerability - stack organization for reading a random address

I'm trying to understand how the format string vulnerabilities can work and how we can read any address.
I can check in real time how inputing "%x %x %x" in a printf will pop elements off the stack just above the string address.
This is how that stack looks once inside the printf:
(...)
0x7fffffffe018: 0x000000000040052c
0x7fffffffe020: 0x00007fffffffe180
0x7fffffffe028: 0x00007fffffffe168
0x7fffffffe030: *0x00007fffffffe48d* << address of argument
0x7fffffffe038: 0x00007ffff7dd4e80
0x7fffffffe040: 0x00007ffff7de9d60
0x7fffffffe048: 0x00007ffff7ffe268
0x7fffffffe050: 0x0000000000000000
0x7fffffffe058: 0x0000000000400563 <</ return address after printf
0x7fffffffe060: 0x00007fffffffe168
0x7fffffffe068: 0x0000000200400440
(...)
and 0x7fffffffe48d is the adress of the "%x %x %x" string further away in memory:
0x7fffffffe469: "/home/.../C/format_string/test"
*0x7fffffffe48d*: "%x %x %x"
0x7fffffffe4ac: "SSH_AGENT_PID=..."
So logically this will output the 3 elements on top of this, ie:
ffffe168 ffffe180 40052c
Now, what I don't understand is, if I put a random address in the parameter, say:
"\x15\xff\x0A\x23 %x %x %x %x %s", why would that "\x15\xff\x0A\x23" be actually stored on the stack and read by the "%s" ?
From what i'm seeing above, only the adress of the whole string is put on the stack (0x00007fffffffe48d) but not the characters (and indeed the address i intend to read) themselves.
Said differently, whatever I put inside my string, I can only control the content of address:
0x7fffffffe48d: "blablabla %x %x %x"
but not what's going popped from the stack.
You are correct, the code does not push the content of the string on the stack.
It merely pushes its address.
Using a buffer overflow technique here will not allow you to overwrite the return address.
Unfortunately you don't show the C code.
The following C code would put its string data on the stack and thus could be exploited.
The following example from: http://insecure.org/stf/smashstack.html
Stack based string - exploitable
void overrunmybuffer(char *str) {
char buffer[16]; <<-- local fixed sized array, stored on the stack.
//should have used `strncpy()`
strcpy(buffer,str); <<-- strcpy will blindly push 256 bytes in a 16 byte buffer
}
void main() {
char large_string[256];
int i;
for( i = 0; i < 255; i++)
large_string[i] = 'A';
overrunmybuffer(large_string);
}
Heap based string - difficult to exploit
In your code the function looks something like this:
void cannotoverrunstack(char *str) {
char *buffer; <<-- pointer to char, only the address is stored on stack
buffer = malloc(16);
strcpy(buffer,str); <<-- some other data in the heap will be overwritten
but not the stack.
}
Note that the data overwrite on the heap may or may not trigger an access violation and may overwrite useful data.
Because of the random way data gets assigned in the heap this is much less useful then overwriting the stack.
The stack frame has a very predictable layout and is thus very manipulatable.
The proper solution to the buffer overrun problem is to never use strcpy but to only use strncpy like so:
Save code for fixed sized buffers
void cannotoverrunmybuffer(char *str) {
char buffer[16]; <<-- local fixed sized array, stored on the stack.
strncpy(buffer,str,sizeof(buffer)-1); <<-- only copy first 15 bytes.
buffer[15] = 0; <<-- !!put terminating 0 in!
}
Do not forget to forcefully zero-terminate your string, or you'll end-up reading past the end of the string, leading to lossage. If you're working with Unicode strings you need to put two terminating 0's in.
Even better would be to use automatically expanding strings like those used in Java or Delphi (System::OpenString in C++).
Buffer overruns are impossible with those because they will automatically scale from 0 to 2GB's.

CString::Format() causes debug assertion

Cstring::Format causes debug assertion in visual studio 2008 at vsprintf.c line 244 with "buffer too small".
//inside the function.
somefile.Open (//open for mode read) //somefile is CFile.
char* buff = new [somefile.GetLength()];
somefile.Read ((void*)buff, somefile.GetLength());
CString cbuff;
cbuff.Format ("%s",buff); //this line causes the debug assertion.
//and so on
Any idea why CString::Format() causes "buffer too small" error ? This doesn't always get debug assertion error.
An alternate solution is:
somefile.Open (//open for mode read) //somefile is CFile.
int buflen = somefile.GetLength();
CString cbuff;
somefile.Read ((void*)cbuff.GetBuffer(buflen), buflen);
cbuff.ReleaseBuffer();
It reads directly into a string buffer instead of the intermediate variable. The CString::GetBuffer() function automatically adds the extra byte to the string which you forgot to do when you allocated the "new char[]".
string end with '\0'
so buffer size will not be enough
The problem is that CFile::Read() does not guarantee that it reads as much data as you ask for. Sometimes it's reading less and leaving your buffer without a null terminator. You have to assume that you might only get one byte on each read call. This will also crash sometimes, when an un-readable memory block immediately follows your buffer.
You need to keep reading the file until you get to the end. Also, the null terminator is generally not written to the file at all, so you shouldn't assume that it will be read in but rather ensure that your buffer is always null-terminated no matter what is read.
In addition, you shouldn't use the file size as the buffer size; there's no reason to think you can read it all in at once, and the file size might be huge, or zero.
You should also avoid manual memory management, and instead of new[]/delete[], use a vector, which will ensure that you don't forget to free the buffer or use delete instead of delete[], and that the memory is released even in case of an exception. (I wouldn't recommend using CString or CFile either, for that matter, but that's another topic...)
// read from the current file position to the end of
// the file, appending whatever is read to the string
CString ReadFile(CFile& somefile, CString& result)
{
std::vector<char> buffer(1024 + 1);
for (;;)
{
int read = somefile.Read(&buffer[0], buffer.size() - 1);
if (read > 0)
{
// force a null right after whatever was read
buffer[read] = '\0';
// add whatever was read to the result
result += &buffer[0];
}
else
{
break;
}
}
}
Note that there's no error handling in this example.

Resources