2

What does a bunch of add byte [rax], al mean? I see a lot of memory addressing point to specific parts of the shared library (.dll) that have for instance, this...

  0x10064faf8      0000           add byte [rax], al
  0x10064fafa      0000           add byte [rax], al
  0x10064fafc      0000           add byte [rax], al
  0x10064fafe      0000           add byte [rax], al
     ; XREFS: DATA 0x10041db20  DATA 0x100545d2c  DATA 0x100546999  DATA 0x1005469b0  DATA 0x100549de0  DATA 0x100549e00  
  0x10064fb00      0000           add byte [rax], al
  0x10064fb02      0000           add byte [rax], al
  0x10064fb04      0000           add byte [rax], al
  0x10064fb06      0000           add byte [rax], al

What is that supposed to indicate to me when I see it? Do those spaces get rewritten or something when the dll is loaded into memory?

  • Looks like it tried to disassemble data. – tkausl Feb 28 '18 at 3:56
  • @tkausl shouldn't DATA should the actual data, and not just add add byte [rax], al? – Evan Carroll Feb 28 '18 at 3:58
  • 1
    I don't know radare2 but I think the 0000 is your data, i.e. its a chunk of empty (zero) memory. – tkausl Feb 28 '18 at 4:01
4

I am adding another answer here because the comment by op is akin to a new question

I'm still confused. If ix has numerious references to the point at which I >!seeked too, why would it be that there is neither data nor code? Why would >!these references be pointed to the padded area or the alignment area?

this is a demo of code which is referenced but doing a pd on reference would yield a bunch of zeros and has nothing to do with alignment or any other artifacts

C:\evancarr>cat evancarr0.cpp
#include <stdio.h>
#include <windows.h>
char somecipher[MAX_PATH + 1];
char curdir[MAX_PATH + 1];
char deccipher[MAX_PATH + 1];
int main(void) {
    GetCurrentDirectoryA(MAX_PATH, curdir);
    int cdlen = strlen(curdir);
    for (int i = 0; i < cdlen; i++) {
        somecipher[i] = curdir[i] ^ 0x1;
    }
    printf("%s\n", somecipher);
    for (int i = 0; i < cdlen; i++) {
        deccipher[i] = somecipher[i] ^ 0x1;
    }
    printf("%s\n", deccipher);
}

compiled and executed

C:\evancarr>cl /Zi /W4 /analyze /EHsc /O2 evancarr0.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.12.25835 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

evancarr0.cpp
Microsoft (R) Incremental Linker Version 14.12.25835.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:evancarr0.exe
/debug
evancarr0.obj

C:\evancarr>evancarr0.exe
B;]dw`ob`ss
C:\evancarr

loading it in radare2 seeking to main and doing a pd on the referenced global buffer (as can be seen the buffer has a lot of xrefs but it is a bunch of zeroes and disassembling throws a bunch of add [eax] , al

C:\evancarr>radare2 -AA evancarr0.exe

[0x004015cd]> s 0x4065a0

[0x004065a0]> pd 5
|              ; JMP XREF from 0x00403161 (sub.KERNEL32.dll_GetCurrentDirectoryA_161)
|           0x004065a0      56             push esi
|           0x004065a1      68380d4600     push 0x460d38 <<<<<<<
|           0x004065a6      6804010000     push 0x104                  ; 260
|           0x004065ab      ff1500304600   call dword [sym.imp.KERNEL32.dll_GetCurrentDirectoryA] ;
0x463000
|           0x004065b1      be380d4600     mov esi, 0x460d38


[0x004065a0]> pd 5 @ 0x460d38 
               ; DATA XREF from 0x004065a1  
               ; DATA XREF from 0x004065b1 
               ; DATA XREF from 0x004065f1 
               ; DATA XREF from 0x00406650 
               ; DATA XREF from 0x004065c0 

            0x00460d38      0000           add byte [eax], al
            0x00460d3a      0000           add byte [eax], al
            0x00460d3c      0000           add byte [eax], al
            0x00460d3e      0000           add byte [eax], al
            0x00460d40      0000           add byte [eax], al


[0x004065a0]> pd 5 @ 0x460c30
               ; DATA XREF from 0x00406658 
               ; DATA XREF from 0x00406663 
               ; DATA XREF from 0x004066a0 
               ; DATA XREF from 0x00406700 
               ; DATA XREF from 0x004065fc 


            0x00460c30      0000           add byte [eax], al
            0x00460c32      0000           add byte [eax], al
            0x00460c34      0000           add byte [eax], al
            0x00460c36      0000           add byte [eax], al
            0x00460c38      0000           add byte [eax], al
[0x004065a0]>
  • This answer truly goes above and beyond and illustrates some misunderstandings that I have. Thanks a ton @blabb. You're a gentleman and a scholar. – Evan Carroll Feb 28 '18 at 23:37
2

you probably have a seek outside of any known function in an area where there is no data or code an area that is a filler to meet alignment requirements of page / section sizes

also called as zero padded area

for example

[0x010546bc]> px 10 ; pd 10
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF

0x010546bc  0000 0000 0000 0000 0000                 ..........
            0x010546bc      0000           add byte [eax], al
            0x010546be      0000           add byte [eax], al
            0x010546c0      0000           add byte [eax], al
            0x010546c2      0000           add byte [eax], al
            0x010546c4      0000           add byte [eax], al
            0x010546c6      0000           add byte [eax], al
            0x010546c8      0000           add byte [eax], al
            0x010546ca      0000           add byte [eax], al
            0x010546cc      0000           add byte [eax], al
            0x010546ce      0000           add byte [eax], al
[0x010546bc]>
  • these are showing up in pdb entries though, why would things be seeking to an area with no data? Why would you ever have more than 8 bytes (64bits) of no-data for alignment? – Evan Carroll Feb 28 '18 at 4:37
  • 2
    if you are on windows please download and read pe coff spec for section alignment , segment alignment etc dont assume that any alginment might be 8 max universally – blabb Feb 28 '18 at 4:52
  • I'm still confused. If ix has numerious references to the point at which I seeked too, why would it be that there is neither data nor code? Why would these references be pointed to the padded area or the alignment area? – Evan Carroll Feb 28 '18 at 20:19
  • your question does not provide enough information to process and reply sensibly what do you think a declaration for a global char [] would look like in the binary space you can refer to the buffer in say sprintf and a bunch of zeroes would be what you would see your query as it stands is vague it may be might be can be are guess work answers based on wyaiwyg (what you ask is what you get) – blabb Feb 28 '18 at 20:28
2
add byte [eax], al 

This instruction is falsly and accidentally blind-translated by disassemblers that don't distinguish between stored buffer/void spans and code segs, to explain what happens here you can refer to this blog section:

ADD has an opcode equal to 0000(h)=00000000 0000 0000(2) where the two last flagbits {d,s} of the command opcode are not set which indicates an addition from a register to an R/M field, s stands for size of transfer that is 8 bites = 2bytes.

The second operand denotes an addition of reg value to local address in EAX, in 32 bits intel ASM, it is encoded 00(h) for the reg AL, I don't know about 86/64x architectures but i guess it's same. Thus you see, mere coincidence.

Void spans are also a case where the program reserves extraspace to store imported DLL functions' entrypoints for locally invoked labels, local constants/strings, or between chunks of any forms of dispersed data.

These types of 0' spans can be frequently remarked in polymophic programs that dump themselves differently in RAM after each execution instance, where they often change their relative EP's and function call addresses in an evasive way against unpackers and any form of code tracking.

A very strong guess that this stream of padded DATA either stored for cache purpose or steganographed should be preceded by a JMP instruction CALL or RET, otherwise, there must be a problem.

See here an example of some debuggers/decompilers that recognize padded DB's and skip over them.

enter image description here

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.