2

I'm doing some security research on FreeRTOS embedded systems and I don't have much information about Arduino. Is there any way to leak function or variable addresses on serial console? I can use avr-nm and avr-objdump but, I may need it for dynamically allocated memory.

It gives:

call of overloaded 'println(void (*)(void*))' is ambiguous

When I try to pass function pointers to serial console.

UPDATE: With using (unsigned char) I can leak something and it is 68 in serial console my code below. I have

000004d0 l     F .text  000000e0 _Z9TaskBlinkPv

from symbols if it is related with TaskBlink.

#include <Arduino_FreeRTOS.h>

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *)"Blink"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  2  // priority
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  Serial.println((unsigned char) &TaskBlink,HEX);
  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;



  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    //Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}

UPDATE 2: When I'm using (unsigned int) it is giving 268 and dissassembling 268 gives:

     262:       9b 8d           ldd     r25, Y+27       ; 0x1b
     264:       8c 8d           ldd     r24, Y+28       ; 0x1c
     266:       98 13           cpse    r25, r24
     268:       05 c0           rjmp    .+10            ; 0x274 <_ZN14HardwareSerial5writeEh+0x24>
     26a:       e8 89           ldd     r30, Y+16       ; 0x10
     26c:       f9 89           ldd     r31, Y+17       ; 0x11
     26e:       80 81           ld      r24, Z
     270:       85 fd           sbrc    r24, 5
     272:       24 c0           rjmp    .+72            ; 0x2bc <_ZN14HardwareSerial5writeEh+0x6c>
     274:       f6 2e           mov     r15, r22

It is not my function nor a tramboline. It is at:

000004d0 <_Z9TaskBlinkPv>:
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
     4d0:       cf 93           push    r28
     4d2:       df 93           push    r29
     4d4:       cd b7           in      r28, 0x3d       ; 61
     4d6:       de b7           in      r29, 0x3e       ; 62
     4d8:       a1 97           sbiw    r28, 0x21       ; 33
     4da:       0f b6           in      r0, 0x3f        ; 63
     4dc:       f8 94           cli
     4de:       de bf           out     0x3e, r29       ; 62
     4e0:       0f be           out     0x3f, r0        ; 63
     4e2:       cd bf           out     0x3d, r28       ; 61

What am I doing wrong?

  • 2
    Post a complete, working copy of your sketch. We can't discuss about unknows. – user31481 Oct 16 '17 at 21:41
  • Are you aware that ATMega is an Harvard arquitecture MCU? Data space and program space are separated. – user31481 Oct 16 '17 at 23:03
  • Yes, but I don't know it's effect on addresses. – user39010 Oct 16 '17 at 23:05
3

The error you have is exactly a factor 2: Your Serial.print() gave 0x0268, whereas TaskBlink(void *) is at address 0x04d0, which is twice 0x0268. Both addresses are correct: it all depends on what you mean by “address”.

Functions live in the microcontroller's flash. At the hardware level, and for the purpose of fetching instructions, the flash is addresses by 16-bit words. This means that address 1 is one word (two bytes) past address 0. Note that for fetching constant “PROGMEM” data, the lpm instruction addresses the flash byte-wise. This may seem inconsistent, but it's the way the hardware is designed. Function pointers are addresses intended to be put into the program counter by means of the icall (indirect call) instruction. This instruction expects a word-wise address, thus function pointers are word-wise addresses.

For some reason – presumably for consistency with other platforms – the authors of the GNU binutils package chose to always use byte-wise addresses. When avr-nm and avr-objdump tell you that TaskBlink(void *) is at address 0x04d0, they mean it starts 0x04d0 bytes after the start of the flash. When Serial.print() tells you it's at 0x0268, it means the address used at the hardware level is 0x0268, and that's because the function starts 0x0268 words after the start of the flash.

1

What you need is

  Serial.println((unsigned int) &TaskBlink, HEX);

The operator "&" gives you an address. In Arduino (ATMega MCU), that is a 16 bit value, that fits inside an unsigned int.

The cast operator "(unsigned int)" means "I will use that value as an unsigned int".

Serial knows how to print numerical values (but not funtion addresses).

  • What symbol? "&"? – user31481 Oct 16 '17 at 23:04
  • Sorry for deleting comment I mean "symbols" used for relocation (for constructing symbol table) and debugging. – user39010 Oct 17 '17 at 10:08
  • I guess some people can read those for debugging purposes after a crash. – user31481 Oct 17 '17 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy