Today I am trying to copy a unsigned long variable into the contents of an unsigned char * variable.
The reasoning for this is, I wrote an RC4 cipher which requires the key input to be a unsigned char *, I am using the SYSTEMTIME class to obtain a value & combining it with a randomly generated long value to obtain my key for RC4 - I am using it as a timestamp for a user created account to mark in my sqlite dbs.
Anyways, the problem I ran into is that I cannot copy the ULONG into PUCHAR.
I've tried
wsprintfA(reinterpret_cast<LPSTR>(ucVar), "%lu", ulVar);
and I've tried
wsprintfA((LPSTR)ucVar, "%lu", ulVar);
However, after executing my program the result in ucVar is just empty, or it doesn't even compute, and crashing the application.
[edit 1]
I thought maybe the memcpy approach would work, so I tried declaring another variable and moving it into ucVar, but it still crashed the application - i.e. It didn't reach the MessageBox():
unsigned char *ucVar;
char tmp[64]; // since ulVar will never be bigger than 63 character + 1 for '\0'
wsprintfA(tmp, "%lu", ulVar);
memcpy(ucVar, tmp, sizeof(tmp));
MessageBox(0, (LPSTR)ucVar, "ucVar", 0);
[/edit 1]
[edit 2]
HeapAlloc() on ucVar with of size 64 fixed my problem, thank you ehnz for your suggestion!
[/edit 2]
Can anyone give me some approach to this problem? It is greatly appreciated!
Regards,
Andrew
Unless you have ownership of memory you're trying to use, all kinds of things can happen. These may range from the error going unnoticed because nothing else already owns that memory, to an instant crash, to a value that disappears because something else overwrites the memory between the time that you set it and the time that you attempt to retrieve a value from it.
Fairly fundamental concepts when dealing with dynamic memory allocation, but quite the trap for the uninitiated.
Related
Fortify reported a buffer overflow vulnerability in below code citing following reason -
In this case we are primarily concerned with the case "Depends upon properties of the data that are enforced outside of the immediate scope of the code.", because we cannot verify the safety of the operation performed by memcpy() in abc.cpp
void create_dir(const char *sys_tmp_dir, const char *base_name,
size_t base_name_len)
{
char *tmp_dir;
size_t sys_tmp_dir_len;
sys_tmp_dir_len = strlen(sys_tmp_dir);
tmp_dir = (char*) malloc(sys_tmp_dir_len + 1 + base_name_len + 1);
if(NULL == tmp_dir)
return;
memcpy(tmp_dir, sys_tmp_dir, sys_tmp_dir_len);
tmp_dir[sys_tmp_dir_len] = FN_LIBCHAR;
memcpy(tmp_dir + sys_tmp_dir_len + 1, base_name, base_name_len);
tmp_dir[sys_tmp_dir_len + base_name_len + 1] = '\0';
..........
..........
}
It appears to me a false positive since we are getting the size of data first, allocating that much amount of space, then calling memcpy with size to copy.
But I am looking for good reasons to convince fellow developer to get rid of current implementation and rather use c++ strings. This issue has been assigned to him. He just sees this a false positive so doesn't want to change anything.
Edit I see quick, valid criticism of the current code. Hopefully, I'll be able to convince him now. Otherwise, I'll hold the baton. :)
Take a look to strlen(), it has input string but it has not an upper bound then it'll go on searching until it founds \0. It's a vulnerability because you'll perform memcpy() trusting its result (if it won't crash because of access violation while searching). Imagine:
create_dir((const char*)12345, baseDir, strlen(baseDir));
You tagged both C and C++...if you're using C++ then std::string will protect you from these issues.
It appears to me a false positive since we are getting the size of data first, allocating that much amount of space
This assumption is a problem that matches the warning/error. In your code, you're assuming that malloc successfully allocated the requested memory. If your system has no memory to spare, malloc will fail and return NULL. When you try to memcpy into tmp_dir, you'd be copying to NULL which would be bad news.
You should check to guarantee that the value returned by malloc is not NULL before considering it as a valid pointer.
I have a basic problem using memcpy and don't understand where the problem is. I show below the relevant parts of the code. The code seg. faults in the last right iteration of the loop. Why can't I index in to an memory area that is reserved?
Thank you in advance.
mystr->data = malloc(2048);
unsigned char buf[8500];
for (i=0;i<32;i++){
offset = i*256;
memcpy(&mystr->data[64*i],&buf[8+offset],64);
}
From the comments it'cs clear that my suspicion was right:
if sizeof( *mystr->data ) > 1 (because e.g. it's unsigned long long *data;) then you run beyond the end of the buffer because the offsets calculated by expressions like &mystr->data[64*i] are relative to the type, here it is mystr->data + 64*i*sizeof(*mystr->data) bytes which was up to 64*31*8 in your code.
You could either change the type, as you have done, or change the offsets (to &mystr->data[8*i] in your case) depending on what what seems 'right' semantically in your context
I am sitting in a class and I am told by a very experienced teacher that the following code will terminate when the STACK memory gets completely filled by the program. Now I am not able to understand why? Below Is the source code :-
#include<stdio.h>
int main()
{
char i;
for (i = 120; i < 130; i++)
printf("\n%d", i);
return 0;
}
Now, the reason I feel that this loop will not terminate is because once the program runs, the variable is declared in one memory location which is not changing till the life of the program and we are only changing the value of the already declared variable. So, I wanted to ask the answer to this question. Also, if you think the teacher is right, please explain as well :)
Also, I tried running the program for a long time but the memory consumption did not increase by even a bit :|
The actions of the program depend on how your implementation defines char: it may be a signed or an unsigned type.
If it is unsigned, it outputs 10 numbers and terminates.
If it is signed, it will wrap at 127 and the next value is -128 - in most implementations. But according to the standard, it is undefined behaviour.
I don't see why it should eat up the complete stack - there is no recursion and no additional memory allocation, so that
told by a very experienced teacher that the following code will terminate when the STACK memory gets completely filled by the program
means "never" - because it just doesn't fill up the stack. It cannot have been such an experienced programmer/teacher – or the OP is not an experienced listener and has misunderstood something the teacher has told him.
the reason is simple as well as tricky :)
i is not an int, but a char.
This means that its range goes from -128 to +127.
While the loop increses the index, it will overflow at +128, so that the value in memory will be -127 again. This means that i is again smaller than 130! The loop continues on and on...
Now continue cheating :P
char is 1byte long -2^8 to 2^8-1 (-128 to 127) if you try to add 1 to 127 it will be -128 an overflow occurs.
printing the variable you will see the same .
change the declartion from
char i to int i
it never fills the stack as you are not declaring new variables or calling functions to fill the stack. so it's an infinite loop only
Yeah it will lead to infinite loop since i has been declared as char which ranges from -128 to +127 so it never reached 130
the time i reaches 127 it comes back to -128 and never reaches 130
http://ideone.com/iVLoHe
I am trying to find MAC address of available "Wi_Fi"s in this area but I receive wrong MAC address( at least I am sure about 1 access point MAC address here that I know is not the same with thing I receive) .
My code is:
char MAC[64];
int len=sizeof(MAC)/sizeof(int);
int i;
for(i=1;i<len;i++){
MyScanResults = WFScanList(i);
//unsigned long long testMac =MyScanResults.bssid[i];
unsigned char* pTestMac = (unsigned char*)&MyScanResults.bssid[i];
sprintf(MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned)pTestMac[6],
(unsigned)pTestMac[5],
(unsigned)pTestMac[4],
(unsigned)pTestMac[3],
(unsigned)pTestMac[2],
(unsigned)pTestMac[1]
);
and my expected answer is:
bssid: 00:12:17:C6:F4:36
but each time I receive some addresses like this and some times this address change also:
MAC: 73:6D:65:36:F4:C6
I have changed also order of numbers but nothing...
is there anyone to tell me where is my problem?
thanks
Regards
Your code doesn't make a lot of sense.
You call MyScanResults = WFScanList(i); before even declaring i. Also, the looping and indexing from 1 is very suspect.
I also think the use of i is very strange throughout, the calculation of a pointer into MyScanResults.bssid, effectively slicing it, can't be right.
I think your loop should be something like:
for(i=0; i < WFNetworkFound; i++)
{
const tWFNetwork myScanResults = WFScanList(i);
sprintf(MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
myScanResult.ssid[0],
myScanResult.ssid[1],
myScanResult.ssid[2],
myScanResult.ssid[3],
myScanResult.ssid[4],
myScanResult.ssid[5]);
This assumes you've run the scan already so that the global variable WFNetworkFound has been updated. It also assumes that you're using openPicus, so that this reference code from which I picked up a thing or two is valid.
Greetings!
I have a simple program in qt on c.
There are two pointers to type short, used to read from file and store bits from values read.
sample code:
//(input is a FILE* which is opened and passed to the function)
//(output is also a FILE* which is also opened and passed to the function)
//1. Variables declaration
short* sample_buffer;
int buffer_size=1;
short samples_read;
unsigned long value_x=7;
short* nzb_buffer;
short buffer_position=-1;
int i;
//2.Memory allocation
sample_buffer= malloc(sizeof(short)*buffer_size);
nzb_buffer = malloc(sizeof(short)*value_x);
....
//3. Read from infile, one short at time, process and write it to outfile
do
{
//3.1. Read from input file
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
//3.2. Switch position inside nzb_buffer one to the right,
// going back to zero if out of bounds
buffer_position=(buffer_position+1)%value_x;
....
//3.3. Put least significant bit of the just read short into nzb_buffer
nzb_buffer[buffer_position]=sample_buffer[0]%2;
....
//3.4. Write the short we just read from infile to the outfile
for (i=0;i<samples_read;i++)
{
fwrite(sample_buffer,sizeof(short),1, output);
}
} while(samples_read==buffer_size);
I've let unreliant pieces of code out. If you need to see something else please tell me.
Problem is, after like 10 or 15 operations of the loop, it crashes with "Segmentation fault" signal. It crashes on the fwrite() function.
I debugged and i use watch on sample_buffer. For some reason, on one exact step, the operation nzb_buffer[buffer_position]=sample_buffer[0]%2 makes sample_buffer become 0x0 (i belive, it becomes a null pointer).
This cannot be overflowing on nzb_buffer because buffer_position for that operation is 3 (out of 7 allocated for the particular array in malloc). And since each loop makes one write operation and shifts the carry, the operation of writing into nzb_buffer[3] has already happened before in the loop and did not nullify the pointer that time.
I am totally clueless what may be happening here.
Anybody has any ideas what is going on or how do i debug it?
Thanks in advance!
PS: Added comments "what the code does"
Your exit condition for the loop seems to be misplaced. I would do:
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
while(samples_read==buffer_size){
[...]
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
}