Reading memory address in GDB - c

I am trying to understand how to read memory address and find out its value using GDB.
In code, I assigned a value:
xyz->a = -1;
In GDB I see this:
(gdb) p xyz->a
$1 = 65535
(gdb) p/x xyz->a
$2 = 0xffff
(gdb) p &(xyz->a)
$3 = (some_type *) 0x172e750
(gdb) x/40xb 0x172e750
0x172e750: 0xff 0xff 0x00 0x00 0x00 0x00 0x00 0x00
0x172e758: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x172e760: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x172e768: 0xc0 0xe0 0x5b 0x01 0x00 0x00 0x00 0x00
0x172e770: 0xd8 0x00 0x00 0x00 0x29 0x00 0x00 0x00
Firstly, how do I read the memory addresses and their values to determine xyz->a value?
Second, looks like there is an Endian issue going on? How do I confirm that?

In memory, they are complements. To confirm endian, you can try to give xyz->a a value such like 0x55aa.

Related

Incrementing an unsigned char array

I have a program that takes in an unsigned char ctr[24]. This is going to be used many times and I would like to have a new ctr for each operation. So I would need to either generate a random value each time, or I could initialize it to 0 and increment. I am after performance so generating a new value each time is probably going to be slow versus just incrementing. Is it possible to increment a unsigned char array?
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Increment it by one...
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
etc..
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x02
Treating unsigned char ctr[24] = {0}; as a counter initialized to 0, the 24 elements can be treated as digits of a base UCHAR_MAX+1 number. Based on the question, the "units" digit is to be stored in ctr[23], the "base1" digit in ctr[22], the "base2" digit in ctr[21], etc. When a digit with value UCHAR_MAX is incremented it will become 0 and a "carry bit" value of 1 needs to be added to the next digit position.
void increment(unsigned char ctr[static 24])
{
unsigned int pos = 24;
while (pos-- && ++ctr[pos] == 0)
;
}
The above function increments an unsigned char[24] in place. It first increments ctr[23] and if it has wrapped around to 0, increments ctr[22], and so forth until one of the digits has not wrapped around to 0, or all of the digits have wrapped around to 0.
You are vanishingly unlikely to really need to....
I mean if you just took the first 8 bytes and treated them as an uint64_t that would run a long, long, time before wrapping around.
Seems to me that some pointer casty stuff and that is job done for any likely use case.
Note that you might need to use some bytes in the middle of your 24 to ensure your memory is aligned suitably for a 64 bit access, but that is a triviality.
void *inc(void *buff, size_t size)
{
unsigned char *cbuff = buff;
for(size_t index = 0; index < size; index++)
{
if(cbuff[index] == 255)
{
cbuff[index] = 0;
}
else
{
cbuff[index]++;
break;
}
}
return buff;
}
I have a program that takes in a unsigned char ctr[24]. This is going to be used many times and I would like to have a new ctr for each operation. So I would need to either generate a random value each time, or I could initialize it to 0 and increment. I am after performance so generating a new value each time is probably going to be slow versus just incrementing. Is it possible to increment a unsigned char array?
Just don't.
Use a simple unsigned long long. It's more than big enough.
At 3 billion increment operations per second, it would take 97 years to roll over a 64-bit value.
unsigned long long is big enough.
Something like this? untested
void add1_recur(unsigned char *x, int lo) {
if (lo < 0) /* 192 bit overflow! */ exit(EXIT_FAILURE);
if (x[lo] == 255) {
x[lo] = 0;
add1_recur(x, lo - 1;)
} else {
x[lo] += 1;
}
}
// add 1 to x; assume x[0] is high order bit
void add1_inplace(unsigned char x[static 24]) {
add1_recur(x, 23);
}
As far as I understand you just need a new pattern each time. Not necessarily a counter.
So would a union do?
Like:
typedef union
{
uint64_t d64[3];
unsigned char d8[24];
} ctr_t;
void p(unsigned char ca[])
{
for (int i=0; i<24; ++i) printf("0x%02X ", ca[i]);
puts("");
}
void change(ctr_t* ctr)
{
// Do some change to each of the three uint64
++ctr->d64[0];
--ctr->d64[1];
++ctr->d64[2];
}
int main(void) {
ctr_t ctr = {{0, 0, 0xff00ff00ff}}; // Just some initialization
p(ctr.d8);
change(&ctr);
p(ctr.d8);
change(&ctr);
p(ctr.d8);
change(&ctr);
p(ctr.d8);
return 0;
}
Output
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 0x00 0x00
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x01 0xFF 0x00 0xFF 0x00 0x00 0x00
0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFE 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x01 0x01 0xFF 0x00 0xFF 0x00 0x00 0x00
0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFD 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 0x01 0xFF 0x00 0xFF 0x00 0x00 0x00

Place array on OCRAM segment in the user application (i.mx6) through linker script

Tried to use the OCRAM (i.mx6) region for storing the keys using the linker script But not able to read/write OCRAM region. The value we are fetching doesn't matches with the OCRAM content dumped using the MMAP call.
Attachments: [https://ufile.io/dpqwy]
modified linker script is attached
The C program used to place the key in the OCRAM attached
program output dumped below.
Map file for c program also attached, where "caterpillar_privkey" looks to be placed at right place.
OCRAM memory map attached
1 modified portion of linker script (full file attached)
MEMORY
{
RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 1024M
IRAM (rwx) : ORIGIN = 0x00910000, LENGTH = (256K - 64K)
}
.mybuf : { KEEP (*(.pseudo_seg .pseudo_seg*)) } > IRAM
2.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define CODE_BASE_ADDR_START 0x910000
__attribute__((section(".pseudo_seg"))) uint8_t caterpillar_privkey[100];
void * MapMemory(unsigned int address, int size)
{
int32_t fd;
void *ret_addr;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
perror("open");
return NULL;
}
ret_addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (ret_addr == MAP_FAILED) {
perror("mmap");
ret_addr = NULL;
}
if (close(fd) == -1) {
perror("close");
}
return ret_addr;
}
int main(void)
{
int32_t k;
void *mem = MapMemory(CODE_BASE_ADDR_START, 4096);
fprintf(stderr, "*********************caterpillar key base =%p\n", caterpillar_privkey);
#if 0
memset(caterpillar_privkey, 0xa, sizeof(caterpillar_privkey));
#endif
fprintf(stderr, "\nDump caterpillar_privkey on iram mem at %p len=%d [linker script region]\n\n", caterpillar_privkey, sizeof(caterpillar_privkey));
for (k = 0; k < sizeof(caterpillar_privkey); k++) {
fprintf(stderr, "0x%02x ", caterpillar_privkey[k]);
}
fprintf(stderr, "\nDump caterpillar_privkey on iram mem at %p len=%d [linker script region] Endddddddddddd\n\n", caterpillar_privkey, sizeof(caterpillar_privkey));
fprintf(stderr, "Dump mem at %p len=%d using mmap to cross check \n\n", mem, sizeof(caterpillar_privkey));
for (k = 0; k < sizeof(caterpillar_privkey); k++) {
fprintf(stderr, "0x%02x ", ((uint8_t *) mem) [k]);
}
fprintf(stderr, "\nDump mem using mmap ndddddddddddddddddddddddd\n\n");
return 0;
}
3 (program output)
# /var/ocram_test
*********************caterpillar key base =0x910000
Dump caterpillar_privkey on iram mem at 0x910000 len=100 [linker script region]
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Dump caterpillar_privkey on iram mem at 0x910000 len=100 [linker script region] Endddddddddddd
Dump mem at 0x76fab000 len=100 using mmap to cross check
**0xec 0x1a 0x42 0x4d** 0xb3 0x62 0x55 0xe2 0x49 0xe6 0xba 0x77 0x96 0x77 0xa4 0x84 0x7b 0x76 0xf0 0x33 0xe2 0x42 0x17 0x88 0xe6 0xbd 0x53 0x5a 0xe5 0x31 0x57 0xaf 0x3d 0xbe 0x8b 0x1a 0x0f 0xba 0x9c 0x17 0x2e
0x31 0xe5 0x39 0xf7 0x65 0x27 0xfa 0x7f 0xc9 0xe2 0x65 0xfb 0xf2 0x13 0xbb 0x0f 0xd2 0x91 0x4f 0xa9 0x84 0x1b 0x2a 0xd2 0x6e 0x86 0xb2 0x29 0xc8 0xd6 0x2c 0x15 0x2b 0xff 0x4d 0xdf 0xbc 0x73 0xbf 0x09 0x61
0xd8 0x73 0x3a 0x89 0xaa 0x7a 0xb3 0x6a 0xcd 0xf0 0x9a 0xa8 0x97 0x3a 0x29 0x31 0xb2 0x32
Dump mem using mmap endddddddddddddddddddddddd
* Dumping memory at the U-boot to make sure same content exist on OCRAM */
U-Boot 2016.03 (Dec 06 2017 - 11:54:13 +0530)
CPU: Freescale i.MX6Q rev1.5 at 792 MHz
Reset cause: WDOG
Board: SABRE Lite
I2C: ready
DRAM: 1 GiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
SF: Detected SST25VF016B with page size 256 Bytes, erase size 4 KiB, total 2 MiB
Display: hdmi:1280x720M#60 (1280x720)
In: serial
Out: serial
Err: serial
Net: Micrel ksz9021 at 7
FEC [PRIME], usb_ether
Hit any key to stop autoboot: 0
Enter passphrase to stop autoboot:
LC3_HAB => md 0x910000
00910000: **4d421aec** e25562b3 77bae649 84a47796 ..BM.bU.I..w.w..
00910010: 33f0767b 881742e2 5a53bde6 af5731e5 {v.3.B....SZ.1W.
00910020: 1a8bbe3d 179cba0f 39e5312e fa2765f7 =........1.9.e'.
00910030: 65e2c97f bb13f2fb 4f91d20f 2a1b84a9 ...e.......O...*
00910040: b2866ed2 2cd6c829 4dff2b15 bf73bcdf .n..)..,.+.M..s.
00910050: 73d86109 7aaa893a f0cd6ab3 3a97a89a .a.s:..z.j.....:
00910060: 32b23129 724ea2b0 02cc1510 564da177 )1.2..Nr....w.MV
00910070: 7b646936 4dd721ad 4b80692f 22ecdc98 6id{.!.M/i.K..."
00910080: 682e525f 5c0bed9a 1218fa32 9ef66eb6 _R.h...\2....n..
00910090: 728c29d8 1197b647 997247c0 37ab36a2 .).rG....Gr..6.7
009100a0: 72c571e1 4c6b3bda 49f2639f c719b88e .q.r.;kL.c.I....
009100b0: 9dca08b3 3a9140cc 2d3baf94 93875366 .....#.:..;-fS..
009100c0: a465e61b 2c6bb79e ce61f195 75e89607 ..e...k,..a....u
009100d0: e53cc9af 4953b4db a497ca23 206f5f87 ..<...SI#...._o
009100e0: ab309c04 03ae7f91 cf2c65cf 017420b4 ..0......e,.. t.
009100f0: b09f5053 5104ac83 ea898c88 3e737bc2 SP.....Q.....{s>

Buffer Overflow explanation

I made this simple password verification program, and I'm trying to overflow the buffer array to change the auth variable to 1 and i managed to do it except I can only change the auth variable to the character 1 and not the decimal 1, how can i do it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char buffer[16];
int auth=0;
strcpy(buffer, argv[1]);
if(strcmp(buffer,"password")==0)
auth=1;
else
auth=0;
if(auth)
printf("Granted");
return 0;
}
Following information is derived from runs on my Ubuntu-14.04 system using gcc version 4.8.4 as my compiler and gdb version 7.7.1 as my debugger
First, the buffer overflow happens as a result of the strcpy function, and if you overflow buf so that it overwrites the memory location of auth, but the following if-else block will overwrite your changes.
Secondly you can see what is happening by looking at the stack in a debugger. I made a slight modification to you code, by initializing auth to 0xbbbbbbbb (just so I can find here auth is located on the stack).
Setting a break point on main and stepping into the function we can examine the values of the various registers:
(gdb) info reg
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffdf30 140737488346928
rsi 0x7fffffffdf18 140737488346904
rdi 0x2 2
rbp 0x7fffffffde30 0x7fffffffde30
rsp 0x7fffffffddf0 0x7fffffffddf0
[... some lines removed ...]
rip 0x400652 0x400652 <main+37>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
From this we can see that the stack extends from 0x7fffffffddf0 to 0x7fffffffde30. Now stopping right before the call to strcpy, we can take a look at the stack:
(gdb) x/76xb $rsp
0x7fffffffddf0: 0x18 0xdf 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffddf8: 0x1d 0x07 0x40 0x00 0x02 0x00 0x00 0x00
0x7fffffffde00: 0x30 0xde 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffde08: 0x00 0x00 0x00 0x00 0xbb 0xbb 0xbb 0xbb
0x7fffffffde10: 0xd0 0x06 0x40 0x00 0x00 0x00 0x00 0x00
0x7fffffffde18: 0x40 0x05 0x40 0x00 0x00 0x00 0x00 0x00
0x7fffffffde20: 0x10 0xdf 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffde28: 0x00 0x2b 0x25 0x07 0xdd 0x7a 0xc0 0x6d
0x7fffffffde30: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffde38: 0x45 0x6f 0xa3 0xf7
Looking at this, we can see that auth is located at a memory address of 0x7fffffffde0c.
I set as a command line argument passwordAAAAAAAA111, and now we can single step across the strcpy call and look at memory again:
(gdb) x/76xb $rsp
0x7fffffffddf0: 0x18 0xdf 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffddf8: 0x1d 0x07 0x40 0x00 0x02 0x00 0x00 0x00
0x7fffffffde00: 0x30 0xde 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffde08: 0x00 0x00 0x00 0x00 0xbb 0xbb 0xbb 0xbb
0x7fffffffde10: 0x70 0x61 0x73 0x73 0x77 0x6f 0x72 0x64
0x7fffffffde18: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x7fffffffde20: 0x31 0x31 0x31 0x31 0x00 0x7f 0x00 0x00
0x7fffffffde28: 0x00 0x2b 0x25 0x07 0xdd 0x7a 0xc0 0x6d
0x7fffffffde30: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffde38: 0x45 0x6f 0xa3 0xf7
(gdb)
From this, we can see that the value of auth has not be touched (notice the four 0xbb still in memory starting at 0x7fffffffde0c). Also we can now see where the password is stored in memory, it starts at 0x7fffffffde10. The four 'A's that I used are where the four 0x41s are and the four '1's that I used are where the four 0x31s are
So, on my system I do not see a way that you would be able to overflow into the auth variable.
Finally, the question that you originally raised, remember that the command line arguments are treated as a character array, so passing in something line AAAA1 on the command line will result in the array [0x41 0x41 0x41 0x41 0x31] being passed to your program. What you want your program to receive is actually [0x41 0x41 0x41 0x41 0x01 0x00 0x00 0x00] (assuming 32-bit, little endian architecture). There are two issues that you will face,
1. 0x01 is a non-printable character
2. 0x00 being the null terminator will stop the string input at the first null.
There is not alot you can do about the issue 2, with just a simple input; however as others have suggested the solution around issue 1 is to create a driver program that builds the input buffer the way that you want and then passes that to the program.
On windows (resp. Linux), create a bat (resp shell) file like this:
a 0123456789ABCDEFG
(a being the name of your executable)
Then, edit it with an hex editor and change the last G to 01 hex value, save.
If (I say if) you can make sure that the address of your integer value comes after the char buffer (which I could not do using my gcc, since the compiler locates its variable with an implementation-based order), run this script and you will see that the \001 char is passed at the end of first argument.
Note: there's no way at all to pass a 0 (null) character as arguments are null-terminated, so if you want to inject some data or code, you will have to do without the zero character.

Initializing Eeprom in IAR on an STM32L0

I want the eeprom to be initialized with certain values but its not working as intended. What am I doing wrong:
From my .icf File in IAR
define symbol __region_EEPROM_start__ = 0x08080030;
define symbol __region_EEPROM_end__ = 0x080807FF;
..
define region EEPROM_region = mem:[from __region_EEPROM_start__ to __region_EEPROM_end__];
..
place in EEPROM_region {rw section .eeprom};
In my Code:
__root char dataE[] # ".eeprom" = {0xFF};
int
main (void)
{
init ()
yet the eeprom does not get initialized correctly, all I get in debug mode is:
0x08080000 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x08080010 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x08080020 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x08080030 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
The EEPROM can be initialized to zero by default by compiler. To initialize to a different value you will have to write it separately and then load it. OR do it in the main in the initialization section.

Find SPS and PPS from private-data

I have web-service which provides me custom format of container which contains H.264 NAL units.
I want to play them via MediaElement in silverlight using custom MediaStreamSource.
According this article I need to set private codec data.
Web service provides me configCodec but in base64 format (looks like "AUIAHv/hABhnQsAe2gMg7+IhAAADAAEAAAMAMo8WLqABAARozgvI")
So, in other platforms (iOS, Android) all I need is set to extra-data property of codec.
codec->extra-data = info;
But in Windows Phone I should provide this info like 00000001 [SPS] 00000001 [PPS].
So, could someone tell me how I can parse provided private data from web-service to get SPS and PPS values from it?
Your data decoded into hex is:
0x01 0x42 0x00 0x1E 0xFF
0xE1
0x00 0x18 (SPS length in bytes)
0x67 0x42 0xC0 0x1E 0xDA 0x03 0x20 0xEF (SPS...)
0xE2 0x21 0x00 0x00 0x03 0x00 0x01 0x00
0x00 0x03 0x00 0x32 0x8F 0x16 0x2E 0xA0 (...SPS)
0x01
0x00 0x04 (PPS length in bytes)
0x68 0xCE 0x0B 0xC8 (PPS)
I don't know what this structure exactly is and where it is rfom, however SPS and PPS are definitely on it.

Resources