How to find the address of a variable when using AVR? - c

I am trying to write a program that detects pixel level collision of bitmaps on a Teensy micro controller compiling with AVR-GCC. I am trying to work out how to calculate the position of a single byte of the bitmap on the screen and have been told I should be using pointers. I don't see the relationship between the physical address of a bitmap byte and it's position on the screen, but I would like to investigate. The problem is, I have no way of printing this address. AVR doesn't have printf and I don't know how to get it to display on the screen. Does anyone have a way of producing this address somehow in the terminal?
i.e. if I have a bitmap and want to print out the address of the first byte, what would I need to write to complete this:
??? *bit = &car_bitmap[1];
???("%??? ", bit);

Use snprintf and send the string to the terminal. It is very costly on the AVR uC. If you use gcc address spaces extensions you may have to link the support for the long numbers.

Assuming you have a working printf(), this should work:
void * const bit = &car_bitmap[1];
printf("%p\n", bit);
Where %p is how to print a void *. Other pointer types should be cast to void * in order to match, but I used a void * for the address into the framebuffer anyway.

Related

Custom regional language

I am writing code in C using 8051 MC at89c51 family to display a regional language in 16x2 lcd displayer.
Because the lcd doesn't read regional languages by default, I create the custom character and I converted each letter into hex. But what I don't understand is where I can put the converted hex value in my code and display as I want?
void main()
{
...
str_lcd("HELLO & WELCOME");
delay_ms(3000);
cmd_lcd(0x80);
cmd_lcd(0x01);
...
}
for "HELLO & WELCOME" the hex value is...
{0x40,0x60,0x30,0x1c,0x14,0x14,0x14,0x14},
{0x78,0x08,0x10,0x20,0x18,0x08,0x08,0x08},
{0x20,0x40,0x7c,0x24,0x24,0x04,0x0a,0x11},
{0x78,0x08,0x10,0x20,0x18,0x08,0x08,0x08},
{0x38,0x28,0x38,0x10,0x38,0x28,0x28,0x28},
{0x44,0x44,0x64,0x24,0x24,0x24,0x24,0x3c},
{0x3c,0x40,0x40,0x20,0x18,0x08,0x08,0x08},
{0x00,0x7f,0x55,0x55,0x55,0x55,0x77,0x00},
{0x7c,0x54,0x54,0x54,0x04,0x04,0x04,0x04},
{0x7c,0x10,0x1c,0x04,0x1f,0x04,0x04,0x04},
{0x48,0x48,0x48,0x4e,0x48,0x48,0x48,0x78},
};
so can any one help me where I can put this hex value and display it on the lcd?
Assuming each 8-byte array corresponds to a specific character, you could have a table of 128 such 8-byte arrays anywhere in the code, for example by having a static array of arrays of constant bytes, like
static const unsigned char character_data[128][8] = {
// Your data here, one entry per character
};
Most of the data in the table above would simply be zero.
Now where you put this table doesn't really matter, the compiler and linker will make sure it ends up in the correct segment (most likely in the text segment with the code). But since I declared it as static it should be placed in the source file which does the translation between the characters and the data sent to the LCD panel.

i try this piece of code in all possible way ,but i cant find why?

Here is the program in C and its output
#include <stdio.h>
#include <conio.h>
void main()
{
int i, t[4], s[4];
for(i=0;i<=3;i++)
{
printf("\n%d",&s[i]);
printf(" %d",&t[i]);
}
for(i=0;i<=3;i++)
{
printf("\n%d %d",&s[i],&t[i]);
}
}
output:
8600 8608
8602 8610
8604 8612
8606 8614
8600 8641
8602 8641
8604 8641
8606 8641
I want to know what exactly happened in second for loop statement that making different from first for loop.
The only obvious problem in your program is that you are passing pointer arguments corresponding to printf's %d format. This is undefined behavior. It can happen to work for some compilation platforms, but you shouldn't count on it.
The most likely explanation is that the ABI for passing pointer arguments to a variadic functions such as printf is, on your platform, different from the ABI for passing int arguments. For all we know, on your platform, pointers are not even the same width as int.
Use the %p format to print a pointer. Or better, use printf("%p", (void*)…);, which is even more portable, in case not all pointer types have the same representation.
The problem is that you are using the wrong format code for printing a pointer. As #PascalCuoq says, you should use %p, not %d.
The reason is that pointers and integers are clearly not the same size, on your system.
When you pass the two pointers to different printf calls %d will print the first part of the pointer value.
When you pass the two pointers to the same printf call, getting the lengths wrong will mean that it will print two different values that do not line up with either pointer.
Your printf statements are printing an integer, put you're putting a pointer (&t[i] means address of the i th element of the t array).
An integer and a pointer are not necessarily the same number of bytes and most implementations of printf takes a fixed number of bytes from the stack for each % field. Also the 'endianism' of the machine will determine whether the least or most significant bit of the address are used as in integer when printf takes its field data from the stack. It looks like you are running on a 16 bit machine with 24 bit addresses and LSB ordering - some kind of micro-controller, I'd guess.
Your arrays are at the memory addresses (converted to hex from your output:
s : 0xC12198
t : 0xC121A0
(24 bit addreses, I think.)
The first loop handles each array seperately in diffierent printf statements, hence you can see the least significant bits of each array incrementing with each iteration.
The second loop tries to handle both arrays in one `printf. So you get values indicating the incrementing part of one of the addresses, plus the second is the most significant part of the address, which is not incrementing, and the second array's address is not output at all.

Preceding zeros are ignored

I am modifying airodump-ng to build a custom application.
I need the output in this format
{AP Mac 1, Station Mac 1},{AP Mac 2, Station Mac 2},...............
To do this I traverse through struct ST_INFO and using multiple strcat calls I generate an array in the above format.
The problem arises when the MAC address contains preceding zeros and this results in data corruption
eg: 0A1B23443311 is saved as A1B23443311
eg: 001B3311ff22 is saved as 1B3311ff22 ( The 0s have been ignored)
What should I do so that data is saved properly when MAC address contains preceding zeros?
The final array is written to a file.
Update: Printing leading 0's in C?
When I tried to print the MAC address the results were the same as given in the above examples but when I used %02x (I learned about it from above link) the problem was solved when I want to print.
Since, I want to save the contents to an array, is there any trick like the %02x for printf.
The struct ST_INFO contains unsigned char st_mac[6] (MAC address is stored in hex format) and my final array is also unsigned char array.
There are multiple ways to do, but if you're using snprintf() or one of its relatives, the %02x (or maybe %02X, or %.2x or %.2X) formats will be useful. For example:
const unsigned char *st_mac = st_info_struct.st_mac;
unsigned char buffer[13];
for (int i = 0; i < 6; i++)
sprintf(&buffer[2*i], "%.2X", st_mac[i]);
(Usually, using snprintf() is a good idea; here, it is unnecessary overkill, though it would not be wrong.)
You should not be using multiple strcat() calls to build up the string. That leads to a quadratic algorithm. If the strings are long (say kilobytes or more), this begins to matter. You also shouldn't be using strcat() because you need to know how long everything is (the string you've created so far, and the string you're adding to it) so that you can ensure you don't overflow your storage space.
if there is a fixed length for all the addresses, just check the length before appending it. If the
length < fixed_length , append difference between the length's number of zeroes.

Format String Vulnerability troubles

So I have this function:
void print_usage(char* arg)
{
char buffer[640];
sprintf(buffer, "Usage: %s [options]\n"
"Randomly generates a password, optionally writes it to /etc/shadow\n"
"\n"
"Options:\n"
"-s, --salt <salt> Specify custom salt, default is random\n"
"-e, --seed [file] Specify custom seed from file, default is from stdin\n"
"-t, --type <type> Specify different encryption method\n"
"-v, --version Show version\n"
"-h, --help Show this usage message\n"
"\n"
"Encryption types:\n"
" 0 - DES (default)\n"
" 1 - MD5\n"
" 2 - Blowfish\n"
" 3 - SHA-256\n"
" 4 - SHA-512\n", arg);
printf(buffer);
}
I wish to utilize a format string vulnerability attack (my assignment). Here is my attempt:
I have an exploit program which fills a buffer with noops and shell code (I have used this program to buffer overflow the same function, so I know its good). Now, I did an object dump of the file to find the .dtors_list address and I got 0x0804a20c, adding 4 bytes to get the end I get 0x804a210.
Next I used gdb to find at what address my noops begin while running my program. Using this I got 0xffbfdbb8.
So up to this point I feel like I'm correct, now I know I want to use format string to copy the noop address into my .dtors_end address. Here is the string I came up with (this is the string I'm providing as user input to the function):
"\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1$n%%.51u%%2$n%%.228u%%3$n%%.64u%%4$n"
This doesn't work for me. The program runs normally and the %s is replaced with the string I input (minus the little endian memory address at the front, and the two percent signs are now one percent sign for some reason).
Anyways, I'm kind of stumped here, any help would be appreciated.
Disclaimer: I'm no expert.
You're passing "\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1$n%%.51u%%2$n%%.228u%%3$n%%.64u%%4$n" as the value of arg? That means that buffer will contain
"Usage:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%.168u%1$n%.51u%2$n%.228u%3$n%.64u%4$n [options]\x0aRandomly..."
Now let's further assume that you're on an x86-32 target (if you're on x86-64, this won't work), and that you're compiling with an optimization level that doesn't put anything in print_usage's stack frame except for the 640-byte buffer array.
Then printf(buffer) will do the following things, in order:
Push the 4-byte address &buffer.
Push a 4-byte return address.
Invoke printf...
Print out "Usage:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08" (a sequence of 23 bytes).
%.168u: Interpret the next argument to printf as an unsigned int and print it in a field of width 168. Since printf has no next argument, this is actually going to print the next thing on the stack; that is, the first four bytes of buffer; that is, "Usag" (0x67617355).
%1$n: Interpret the second argument to printf as a pointer to int and store 23+168 at that location. This stores 0x000000bf in location 0x67617355. So this is your main problem: You should have used %2$n instead of %1$n and added one junk byte to the front of your arg. (Incidentally, notice that GNU says "If any of the formats has a specification for the parameter position all of them in the format string shall have one. Otherwise the behavior is undefined." So you should go through and add 1$s to all your %us just to be on the safe side.)
%.51u: Print another 51 bytes of garbage.
%2$n: Interpret the third argument to printf as a pointer to int and store 0x000000f2 in that garbage location. As above, this should have been %3$n.
... etc. etc. ...
So, your major bug here is that you forgot to account for the "Usage: " prefix.
I assume you were trying to store the four bytes 0xffbfdbb8 into address 0x804a210. Let's say you'd gotten that to work. But then what would your next step be? How do you get the program to treat the four-byte quantity at 0x804a210 as a function pointer and jump through it?
The traditional way to exploit this code would be to exploit the buffer overflow in sprintf, rather than the more complicated "%n" vulnerability in printf. You just need to make your arg roughly 640 characters long and make sure that the 4 bytes of it that correspond to print_usage's return address contain the address of your NOP sled.
Even that part is tricky, though. You might conceivably be running into something related to ASLR: just because your sled exists at address 0xffbfdbb8 in one run doesn't mean it'll exist at that same address in the next run.
Does this help?

format string vulnerability - printf

Why does this print the value of the memory address at 0x08480110? I'm not sure why there are 5 %08x arguments - where does that take you up the stack?
address = 0x08480110
address (encoded as 32 bit le string): "\x10\x01\x48\x08"
printf ("\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s|");
This example is taken from page 11 of this paper http://crypto.stanford.edu/cs155/papers/formatstring-1.2.pdf
I think that the paper provides its printf() examples in a somewhat confusing way because the examples use string literals for format strings, and those don't generally permit the type of vulnerability being described. The format string vulnerability as described here depends on the format string being provided by user input.
So the example:
printf ("\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s|");
Might better be presented as:
/*
* in a real program, some user input source would be copied
* into the `outstring` buffer
*/
char outstring[80] = "\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s|";
printf(outstring);
Since the outstring array is an automatic, the compiler will likely put it on the stack. After copying the user input to the outstring array, it'll look like the following as 'words' on the stack (assuming little endian):
outstring[0c] // etc...
outstring[08] 0x30252e78 // from "x.%0"
outstring[04] 0x3830255f // from "_%08"
outstring[00] 0x08480110 // from the ""\x10\x01\x48\x08"
The compiler will put other items on the stack as it sees fit (other local variables, saved registers, whatever).
When the printf() call is about to be made, the stack might look like:
outstring[0c] // etc...
outstring[08] 0x30252e78 // from "x.%0"
outstring[04] 0x3830255f // from "_%08"
outstring[00] 0x08480110 // from the ""\x10\x01\x48\x08"
var1
var2
saved ECX
saved EDI
Note that I'm completely making those entries up - each compiler will use the stack in different ways (so a format string vulnerability has to be custom crafted for a particular exact scenario. In other words, you won't always use 5 dummy format specifiers like in this example - as the attacker you'd need to figure out how many dummies the particular vulnerability would need.
Now to call printf(), the argument (the address of outstring) is pushed on to the stack and printf() is called, so the argument area of the stack looks like:
outstring[0c] // etc...
outstring[08] 0x30252e78 // from "x.%0"
outstring[04] 0x3830255f // from "_%08"
outstring[00] 0x08480110 // from the ""\x10\x01\x48\x08"
var1
var2
var3
saved ECX
saved EDI
&outstring // the one real argument to `printf()`
However, printf doesn't really know anything about how many arguments have been placed on the stack for it - it goes by the format specifiers it finds in the format string (the one argument it's 'sure' to get). So printf() gets the format string argument and starts processing it. When it gets to the 1st "%08x" that will correspond to the 'saved EDI' in my example, then next "%08x" will print the
saved ECX' and so on. So the "%08x" format specifiers are just eating up data on the stack until it gets back to the string the attacker was able to input. Determining how many of those are needed is something an attacker would do by a kind of trial and error (probably by a test run that has a whole slew of "%08x" formats until he can 'see' where the format string starts).
Anyway, when printf() gets to processing the "%s" format specifier, it has consumed all the stack entries up to where the outstring buffer resides. The "%s" specifier treats its stack entry as a pointer, and the string that the user has put into that buffer has been carefully crafted to have a binary representation of 0x08480110, so printf() will print out whatever is at that address as an ASCIIZ string.
You have 6 format specifiers (5 lots of %08x and one of %s), but you do not provide values for those format specifiers. You immediately fall into the realm of undefined behaviour - anything could happen and there is no wrong answer.
However, in the normal course of events, the values passed to printf() would have been stored on the stack, so the code in printf() reads values off the stack as if the extra values had been passed. The function return address is on the stack, too. There is no guarantee that I can see that the value 0x08480110 will actually be produced. This sort of attack very much depends on the the specific program and faulty function call, and you might well get a very different value. The example code is most likely written assuming a 32-bit Intel (little-endian) CPU - rather than a 64-bit or big-endian CPU.
Adapting the code fragment, compiling it into a complete program, ignoring the compilation warnings, using a 32-bit compilation on MacOS X 10.6.7 with GCC 4.2.1 (XCode 3), the following code:
#include <stdio.h>
static void somefunc(void)
{
printf("AAAAAAAAAAAAAAAA.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.|%s|\n");
}
int main(void)
{
char buffer[160] =
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz01234";
somefunc();
return 0;
}
produces the following result:
AAAAAAAAAAAAAAAA.0x000000A0.0xBFFFF11C.0x00001EC4.0x00000000.0x00001E22.0xBFFFF1C8.0x00001E5A.|abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz01234|
As you can see, I eventually 'found' the string in the main program from the printf() statement. When I compiled it in 64-bit mode, I got a core dump instead. Both results are perfectly correct; the program invokes undefined behaviour, so anything the program does is valid. If you're curious, search for 'nasal demons' for more information on undefined behaviour.
And get used to experimenting with these sorts of issues.
Another variation
#include <stdio.h>
static void somefunc(void)
{
char format[] =
"AAAAAAAAAAAAAAAA.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n"
".0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n"
".0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n";
printf(format, 1);
}
int main(void)
{
char buffer[160] =
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz012345"
"abcdefghijklmnopqrstuvwxyz01234";
somefunc();
return 0;
}
This produces:
AAAAAAAAAAAAAAAA.0x00000001.0x00000099.0x8FE467B4.0x41000024.0x41414141
.0x41414141.0x41414141.0x2E414141.0x30257830.0x302E5838.0x38302578.0x78302E58
.0x58383025.0x2578302E.0x2E583830.0x30257830.0x2E0A5838.0x30257830.0x302E5838
You might recognize the format string in the hex output - 0x41 is capital A, for example.
The 64-bit output from that code is both similar and different:
AAAAAAAAAAAAAAAA.0x00000001.0x00000000.0x00000000.0xFFE0082C.0x00000000
.0x41414141.0x41414141.0x2578302E.0x30257830.0x38302578.0x58383025.0x0A583830
.0x2E583830.0x302E5838.0x78302E58.0x2578302E.0x30257830.0x38302578.0x38302578
You misunderstood the paper.
The text you linked is assuming that the current position on the stack is 0x08480110 (look at the surrounding text). The printf() will dump data from wherever on the stack you happen to be.
The \x10\x01\x48\x08 at the beginning of the format string is merely to print the (assumed) address to stdout in front of the dumped data. In no way do these numbers modify the address from which the data is dumped.
You're correct about "take you up the stack", but only barely; it relies on the assumption that arguments are passed on the stack, rather than in registers. (Which, for a variadic function is probably a safe assumption, but still an assumption about implementation details.)
Each %08x asks for the 'next unsigned int argument' to be printed in hex; what actually occurs in that 'next argument' location is both architecture and compiler dependent. If you compare the values you get with /proc/self/maps for the process, you might be able to narrow down what some of the numbers mean.

Resources