2017-12-22 10 views
0

Ich erstelle OpenSSL-1.0.2n mit -g 386 freigegebene Option (um mit der Basisversion der Assembly zu arbeiten), um die shared library libcrypto.so.1.0.0 zu erzeugen.Wie kann ich den Offset und die Daten aus dem Textbereich einer freigegebenen Bibliothek erhalten?

Im crypto/aes-Ordner wird aes-x86_64.s generiert und es hat verschiedene globale Funktionen/Labels. Die Gesamtzahl der Zeilen in aes-x86_64.s ist 2535 und verschiedene Beschriftungen sind an verschiedenen Stellen (oder Zeilennummern in der .s-Datei) vorhanden.

328  .globl AES_encrypt 
     .type AES_encrypt,@function 
     .align 16 
     .globl asm_AES_encrypt 
     .hidden asm_AES_encrypt 
     asm_AES_encrypt: 
334  AES_encrypt: 


775  .globl AES_decrypt 
     .type AES_decrypt,@function 
     .align 16 
     .globl asm_AES_decrypt 
     .hidden asm_AES_decrypt 
     asm_AES_decrypt: 
781  AES_decrypt: 


844  .globl private_AES_set_encrypt_key 
     .type private_AES_set_encrypt_key,@function 
     .align 16 
847  private_AES_set_encrypt_key: 


1105 .globl private_AES_set_decrypt_key 
     .type private_AES_set_decrypt_key,@function 
     .align 16 
1108 private_AES_set_decrypt_key: 


1292 .globl AES_cbc_encrypt 
     .type AES_cbc_encrypt,@function 
     .align 16 

     .globl asm_AES_cbc_encrypt 
     .hidden asm_AES_cbc_encrypt 
     asm_AES_cbc_encrypt: 
1299 AES_cbc_encrypt: 


1750 .LAES_Te: 
.long 0xa56363c6,0xa56363c6 
.long 0x847c7cf8,0x847c7cf8 
.long 0x997777ee,0x997777ee 
.long 0x8d7b7bf6,0x8d7b7bf6 
.long 0x0df2f2ff,0x0df2f2ff 
.long 0xbd6b6bd6,0xbd6b6bd6 

.... 
.... 


2140 .LAES_Td: 
.long 0x50a7f451,0x50a7f451 
.long 0x5365417e,0x5365417e 
.long 0xc3a4171a,0xc3a4171a 
.long 0x965e273a,0x965e273a 
.long 0xcb6bab3b,0xcb6bab3b 

AES_cbc_encrypt ist globale Funktion in Zeile Nummer deklariert 776 und Label AES_cbc_encrypt bei Zeilennummer 781.

lokalen Label .LAES_Te und .LAES_Td sind bei der Zeilennummer 1750 und 2140 jeweils wo lange Daten gespeichert sind.

Ich kann auf globales Label AES_cbc_encrypt von Assemblydatei von einem anderen C-Programm zugreifen, indem ich mit shared library verknüpfe.

//test_glob.c 
#include <stdlib.h> 

extern void* AES_cbc_encrypt() ; 

int main() 
{ 

    long *p; 
    int i; 
    p=(long *)(&AES_cbc_encrypt); 
    for(i=0;i<768;i++) 
    { 
     printf("p+%d %p %x\n",i, p+i,*(p+i)); 
    } 

} 

gcc test_glob.c -lcryto 
./a.out 

This gives some random output and later segmentation fault. 

Es muss ein Weg gibt die Offset diesen Datenabschnitt (lokales Label .LAES_Te und .LAES_Td) von den globalen Label AES_cbc_encrypt zu finden so dass die Daten in der Verschlüsselung/Entschlüsselung verwendet werden .

Ich habe folgende Fragen.

1. Wie die von den globalen Label AES_cbc_encrypt zu, so dass lokales Label .LAES_Te und .LAES_Td Offset zu finden, basierend auf , die ich Offset-Daten von einem anderen C-Programm zugreifen kann?

2. Gibt es eine andere Möglichkeit, auf diese Daten der Montagedatei von C-Programm zuzugreifen?

3. Gibt es eine Möglichkeit, den Speicherort im Speicher zu finden, in dem diese Daten geladen sind, und auf diesen Speicherort zuzugreifen, um auf Daten zuzugreifen?

Ich benutze gcc-5.4 Linux Ubuntu 16.04. Jede Hilfe oder Verbindung wird sehr geschätzt. Danke im Voraus.

EDIT 1:

readelf -a aes-x86_64.o erzeugt Ausgangs folgende.

ELF Header: 
    Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
    Class:        ELF64 
    Data:        2's complement, little endian 
    Version:       1 (current) 
    OS/ABI:       UNIX - System V 
    ABI Version:      0 
    Type:        REL (Relocatable file) 
    Machine:       Advanced Micro Devices X86-64 
    Version:       0x1 
    Entry point address:    0x0 
    Start of program headers:   0 (bytes into file) 
    Start of section headers:   14672 (bytes into file) 
    Flags:        0x0 
    Size of this header:    64 (bytes) 
    Size of program headers:   0 (bytes) 
    Number of program headers:   0 
    Size of section headers:   64 (bytes) 
    Number of section headers:   16 
    Section header string table index: 13 

Section Headers: 
    [Nr] Name    Type    Address   Offset  Size    EntSize   Flags Link Info Align 
    [ 0]     NULL    0000000000000000 00000000  0000000000000000 0000000000000000   0  0  0 
    [ 1] .text    PROGBITS   0000000000000000 00000040  0000000000002e40 0000000000000000 AX  0  0  64 
    [ 2] .rela.text  RELA    0000000000000000 00003808  0000000000000018 0000000000000018 I  14  1  8 
    [ 3] .data    PROGBITS   0000000000000000 00002e80  0000000000000000 0000000000000000 WA  0  0  1 
    [ 4] .bss    NOBITS   0000000000000000 00002e80  0000000000000000 0000000000000000 WA  0  0  1 
    [ 5] .note.GNU-stack PROGBITS   0000000000000000 00002e80  0000000000000000 0000000000000000   0  0  1 
    [ 6] .debug_line  PROGBITS   0000000000000000 00002e80  00000000000005a4 0000000000000000   0  0  1 
    [ 7] .rela.debug_line RELA    0000000000000000 00003820  0000000000000018 0000000000000018 I  14  6  8 
    [ 8] .debug_info  PROGBITS   0000000000000000 00003424  0000000000000071 0000000000000000   0  0  1 
    [ 9] .rela.debug_info RELA    0000000000000000 00003838  0000000000000060 0000000000000018 I  14  8  8 
    [10] .debug_abbrev  PROGBITS   0000000000000000 00003495  0000000000000014 0000000000000000   0  0  1 
    [11] .debug_aranges PROGBITS   0000000000000000 000034b0  0000000000000030 0000000000000000   0  0  16 
    [12] .rela.debug_arang RELA    0000000000000000 00003898  0000000000000030 0000000000000018 I  14 11  8 
    [13] .shstrtab   STRTAB   0000000000000000 000038c8  0000000000000085 0000000000000000   0  0  1 
    [14] .symtab   SYMTAB   0000000000000000 000034e0  0000000000000228 0000000000000018   15 14  8 
    [15] .strtab   STRTAB   0000000000000000 00003708  00000000000000fb 0000000000000000   0  0  1 
Key to Flags: 
    W (write), A (alloc), X (execute), M (merge), S (strings), l (large) 
    I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) 
    O (extra OS processing required) o (OS specific), p (processor specific) 

There are no section groups in this file. 

There are no program headers in this file. 

Relocation section '.rela.text' at offset 0x3808 contains 1 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
000000000fc0 001600000002 R_X86_64_PC32  0000000000000000 OPENSSL_ia32cap_P - 4 

Relocation section '.rela.debug_line' at offset 0x3820 contains 1 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
000000000030 000100000001 R_X86_64_64  0000000000000000 .text + 0 

Relocation section '.rela.debug_info' at offset 0x3838 contains 4 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
000000000006 000a0000000a R_X86_64_32  0000000000000000 .debug_abbrev + 0 
00000000000c 000b0000000a R_X86_64_32  0000000000000000 .debug_line + 0 
000000000010 000100000001 R_X86_64_64  0000000000000000 .text + 0 
000000000018 000100000001 R_X86_64_64  0000000000000000 .text + 2e40 

Relocation section '.rela.debug_aranges' at offset 0x3898 contains 2 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
000000000006 00090000000a R_X86_64_32  0000000000000000 .debug_info + 0 
000000000010 000100000001 R_X86_64_64  0000000000000000 .text + 0 

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported. 

Symbol table '.symtab' contains 23 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 SECTION LOCAL DEFAULT 1 
    2: 0000000000000000  0 SECTION LOCAL DEFAULT 3 
    3: 0000000000000000  0 SECTION LOCAL DEFAULT 4 
    4: 0000000000000000 483 FUNC LOCAL DEFAULT 1 _x86_64_AES_encrypt 
    5: 00000000000001f0 609 FUNC LOCAL DEFAULT 1 _x86_64_AES_encrypt_compa 
    6: 0000000000000520 465 FUNC LOCAL DEFAULT 1 _x86_64_AES_decrypt 
    7: 0000000000000700 737 FUNC LOCAL DEFAULT 1 _x86_64_AES_decrypt_compa 
    8: 0000000000000ae0 649 FUNC LOCAL DEFAULT 1 _x86_64_AES_set_encrypt_k 
    9: 0000000000000000  0 SECTION LOCAL DEFAULT 8 
    10: 0000000000000000  0 SECTION LOCAL DEFAULT 10 
    11: 0000000000000000  0 SECTION LOCAL DEFAULT 6 
    12: 0000000000000000  0 SECTION LOCAL DEFAULT 11 
    13: 0000000000000000  0 SECTION LOCAL DEFAULT 5 
    14: 0000000000000460 177 FUNC GLOBAL DEFAULT 1 AES_encrypt 
    15: 0000000000000460  0 NOTYPE GLOBAL HIDDEN  1 asm_AES_encrypt 
    16: 00000000000009f0 184 FUNC GLOBAL DEFAULT 1 AES_decrypt 
    17: 00000000000009f0  0 NOTYPE GLOBAL HIDDEN  1 asm_AES_decrypt 
    18: 0000000000000ab0 35 FUNC GLOBAL DEFAULT 1 private_AES_set_encrypt_k 
    19: 0000000000000d70 541 FUNC GLOBAL DEFAULT 1 private_AES_set_decrypt_k 
    20: 0000000000000f90 1411 FUNC GLOBAL DEFAULT 1 AES_cbc_encrypt 
    21: 0000000000000f90  0 NOTYPE GLOBAL HIDDEN  1 asm_AES_cbc_encrypt 
    22: 0000000000000000  0 NOTYPE GLOBAL DEFAULT UND OPENSSL_ia32cap_P 

No version information found in this file. 

EDIT 2:

nm aes-x86_64.o erzeugt folgenden Ausgabe.

0000000000000f90 T AES_cbc_encrypt 
00000000000009f0 T AES_decrypt 
0000000000000460 T AES_encrypt 
0000000000000f90 T asm_AES_cbc_encrypt 
00000000000009f0 T asm_AES_decrypt 
0000000000000460 T asm_AES_encrypt 
       U OPENSSL_ia32cap_P 
0000000000000d70 T private_AES_set_decrypt_key 
0000000000000ab0 T private_AES_set_encrypt_key 
0000000000000520 t _x86_64_AES_decrypt 
0000000000000700 t _x86_64_AES_decrypt_compact 
0000000000000000 t _x86_64_AES_encrypt 
00000000000001f0 t _x86_64_AES_encrypt_compact 
0000000000000ae0 t _x86_64_AES_set_encrypt_key 

bearbeiten 3:

nm -a ergibt folgende Ausgabe

0000000000000f90 T AES_cbc_encrypt 
00000000000009f0 T AES_decrypt 
0000000000000460 T AES_encrypt 
0000000000000f90 T asm_AES_cbc_encrypt 
00000000000009f0 T asm_AES_decrypt 
0000000000000460 T asm_AES_encrypt 
0000000000000000 b .bss 
0000000000000000 d .data 
0000000000000000 N .debug_abbrev 
0000000000000000 N .debug_aranges 
0000000000000000 N .debug_info 
0000000000000000 N .debug_line 
0000000000000000 n .note.GNU-stack 
       U OPENSSL_ia32cap_P 
0000000000000d70 T private_AES_set_decrypt_key 
0000000000000ab0 T private_AES_set_encrypt_key 
0000000000000000 t .text 
0000000000000520 t _x86_64_AES_decrypt 
0000000000000700 t _x86_64_AES_decrypt_compact 
0000000000000000 t _x86_64_AES_encrypt 
00000000000001f0 t _x86_64_AES_encrypt_compact 
0000000000000ae0 t _x86_64_AES_set_encrypt_key 
+0

Alle Elemente, auf die extern zugegriffen werden soll, sollten in den zugehörigen Header-Dateien deklariert werden. –

+0

1) ja, finde es einfach in der Binärdatei selbst 3) Sobald Sie den Offset haben, können Sie natürlich einfach hinzufügen, um die globale Symboladresse – Jester

+0

@ Jester, wie der Offset von Binär zu finden? Ich benutze readelf und nm, aber nicht in der Lage zu verstehen, wie man Offset von AES_cbc_encrypt zu .LAES_Te/Td findet. – bholanath

Antwort

0

Wenn Sie ein Fest-Code-Offset auf Basis dieser Version der Bibliothek, könnte es mit einem anderen brechen Version, die Änderungen in aes-x86_64.s hat.

So sollten Sie eine .globl foo und foo: Etikett an der .s an der Position der Daten, die Sie zugreifen möchten hinzufügen, und erklären es in C als extern uint32_t foo[].


Dann werden die normalen Code-gen Mechanismen für statische Daten von einer gemeinsam benutzten Bibliothek zugreifen, werden in treten. (D.h. Laden der Adresse aus der GOT falls erforderlich).

Auch, wenn Sie mit -fno-plt kompilieren, &AES_cbc_encrypt wird die Adresse des PLT Stub/Wrapper, nicht die eigentliche Funktion in der Bibliothek sein.


Wenn Sie es brauchen nur mit einem bestimmten Build der Bibliothek zu arbeiten:

Dann mit Ich denke, ja -fno-plt, kompiliert die Adresse einer Funktion in der Bibliothek unter/Montage zu einer Laden von der GOT, so erhalten Sie die tatsächliche Adresse nach der dynamischen Verknüpfung. -fno-plt ist wichtig für dieses zu arbeiten.

Es könnte ziemlich weit weg sein, wenn es in einem anderen Abschnitt ist (.rodata wahrscheinlich .text wahrscheinlich), so dass Ihr einfacher Scan von 768 * 4 Bytes die Tabelle nicht finden kann.

Eine bessere Art der Versatz von einem Symbol finden Sie & auf in C verwenden können:

Verwenden Sie einen Debugger: einstufiges in eine Funktion, die die Daten verwendet, und das finden, was Adresse aus es zu laden (gdb die eingebaute Demontage sollte funktionieren).

Oder disassemblieren Sie die Binärdatei und betrachten Sie den Reliance-Versatz des Little-Endian in einer RIP-relativen Last oder LEA der Tabellenadresse. (Dieser Offset wird zur Laufzeit nicht behoben). Sehen Sie sich die asm-Quelle an, um eine Anweisung zu finden, die auf das gewünschte verborgene Symbol verweist, und finden Sie dann diese Anweisung in der Disassemblierung.

Dadurch erhalten Sie die Entfernung in Bytes vom Ende dieser Anweisung zur Tabelle. Sie können wahrscheinlich den Abstand von dieser Anweisung zu einem Symbol sehen, dem Sie die Adresse von C entnehmen können (wie Sie es mit dem Funktionszeiger machen). Außerdem wird der Disassembler absolute Adressen (relativ zu einer beliebigen Basis) für Ladeadressen und für Symbole/Anweisungen eingeben, so dass Sie diese subtrahieren können.

+0

@PeterCode. Vielen Dank für Ihre schnelle Antwort. Es ist in Ordnung, auch wenn es mit einer bestimmten Version der Bibliothek mit fest codierten Offset funktioniert. – bholanath

+0

Änderung der Bibliothek ist in meinem Fall nicht akzeptabel. Will -fno-plt Option während der Kompilierung und dann meine Methode des Zugriffs auf & AES_cbc_encrypt geben Zugriff auf Daten? – bholanath

+0

@bholanath: Ich denke vielleicht. Mit '-fno-plt' wird die Adresse einer statischen Funktion zu einer Last von der GOT der tatsächlichen Adresse nach der dynamischen Verknüpfung kompiliert/assembliert. Aber es könnte ziemlich weit weg sein, wenn es in einem anderen Bereich ist ('.rodata' statt' .text' wahrscheinlich), also könnte Ihr einfacher Scan von 768 * 4 Bytes es nicht finden. –

Verwandte Themen