Reverse Engineering for Beginners

(avery) #1

CHAPTER 18. ARRAYS CHAPTER 18. ARRAYS


dq offset aMarch_1 ; "March"
dq offset aApril_1 ; "April"
dq offset aMay_1 ; "May"
dq offset aJune_1 ; "June"
dq offset aJuly_1 ; "July"
dq offset aAugust_1 ; "August"
dq offset aSeptember_1 ; "September"
dq offset aOctober_1 ; "October"
dq offset aNovember_1 ; "November"
dq offset aDecember_1 ; "December"
aJanuary_1 db 'January',0 ; DATA XREF: sub_140001020+4
; .data:off_140011000
aFebruary_1 db 'February',0 ; DATA XREF: .data:0000000140011008
align 4
aMarch_1 db 'March',0 ; DATA XREF: .data:0000000140011010
align 4
aApril_1 db 'April',0 ; DATA XREF: .data:0000000140011018


Month names are came right after. Our program is tiny, so there isn’t much data to pack in the data segment, so it just the
month names. But it should be noted that there might be reallyanything that linker has decided to put by chance.


So what if 12 is passed to the function? The 13th element will be returned. Let’s see how the CPU treats the bytes there as
a 64-bit value:


Listing 18.16: Executable file in IDA

off_140011000 dq offset qword_140011060
; DATA XREF: .text:0000000140001003
dq offset aFebruary_1 ; "February"
dq offset aMarch_1 ; "March"
dq offset aApril_1 ; "April"
dq offset aMay_1 ; "May"
dq offset aJune_1 ; "June"
dq offset aJuly_1 ; "July"
dq offset aAugust_1 ; "August"
dq offset aSeptember_1 ; "September"
dq offset aOctober_1 ; "October"
dq offset aNovember_1 ; "November"
dq offset aDecember_1 ; "December"
qword_140011060 dq 797261756E614Ah ; DATA XREF: sub_140001020+4
; .data:off_140011000
aFebruary_1 db 'February',0 ; DATA XREF: .data:0000000140011008
align 4
aMarch_1 db 'March',0 ; DATA XREF: .data:0000000140011010


And this is 0x797261756E614A. Soon after, some other function (presumably, one that processes strings) may try to read
bytes at this address, expecting a C-string there. Most likely it is about to crash, because this value does’t look like a valid
address.


Array overflow protection


If something can go wrong, it will

Murphy’s Law

It’s a bit naïve to expect that every programmer who use your function or library will never pass an argument larger than



  1. There exists the philosophy that says “fail early and fail loudly” or “fail-fast”, which teaches to report problems as early
    as possible and stop. One such method in C/C++ is assertions. We can modify our program to fail if an incorrect value is
    passed:


Listing 18.17: assert() added

const char* get_month1_checked (int month)
{
assert (month<12);
return month1[month];
};


The assertion macro checks for valid values at every function start and fails if the expression is false.

Free download pdf