Biblioteka assemblera x64 C/C++

Biblioteka assemblera x64 C/C++
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
  • Postów:399
0

Cześć,

potrzebuję biblioteki, która ze stringa potrafi wygenerować bytecode assemblera x64. Problem podobny do: http://stackoverflow.com/questions/17001094/c-library-x86-x64-assembler
Jednak mnie nie stać na użycie LLVM (a w zasadzie to libclang, które waży 50MB), i przydałby mi się jakiś tiny assembler x64.

Podkreślam, że chodzi o bibliotekę. Wywołanie jakiegoś kompilatora/assemblera z poziomu systemu odpada, dołączanie dllki >10 MB też odpada, inline assembly nawet nie mam, dołączanie plików .asm do projektu odpada.
Moje poszukiwania nie skończyły się znalezieniem czegokolwiek co by się nadawało, ale być może wy macie jakieś pomysły.

Dodam, że potrzebne mi to tylko do trywialnych instrukcji, typu:

Kopiuj
mov rcx, rdx
mov rcx, [rsp+0x100]
movq r9, xmm2

Asm/C/C++
edytowany 2x, ostatnio: mwl4
KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
1
mwl4
Ręki sobie uciąć nie dam, ale z readme wynika, że to jest libka do deasemblacji, a mi trzeba na odwrót (do deasemblacji już używam capstone).
KA
https://github.com/radare/radare2/blob/master/libr/include/r_asm.h Tutaj jest coś znowu typu "r_asm_rasm_assemble", ja też nie wiem, ale wiem, że niektóre toole z r2 potrafiły generować kod maszynowy nawet z takich wycinków asemblera.
02
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 8 lat
  • Postów:1176
1

Biblioteka do programatycznego generowania assemblera:
https://github.com/asmjit/asmjit (~250k)
Jak koniecznie chcesz ze stringa to jest biblioteka, ktora bazuje na asmjit:
https://github.com/asmjit/asmtk

edytowany 2x, ostatnio: 0x200x20
Zobacz pozostałe 2 komentarze
mwl4
asmjit może i tak, ale asmtk wspiera tylko x86 z tego co widzę.
02
Zgodnie z tym blogiem: https://asmbits.blogspot.com/2016/07/introducing-asmtk.html wspiera takze x64. Ale nie sprawdzalem.
mwl4
No nie wiem, z tego co widzę po kodzie źródłowym asmtk, to tam tylko x86 jest. Choćby tutaj: https://github.com/asmjit/asmtk/blob/master/src/asmtk/asmparser.cpp
02
Tak sie zastanawiam dlaczego koniecznie potrzebujesz stringow i nie chcesz uzyc programatycznego generowania? Wczytujesz tego assemblera gdzies z zewnatrz?
mwl4
Te instrukcje są wstawiane przed wywołaniem mojej funkcji z hooka. Hook jest ustawiany tam gdzie można pobrać pewne wartości, więc te instrukcje służą tylko temu aby te wartości wstawić do odpowiednich argumentów (aby w mojej funkcji były jako argumenty). Przykład: http://pastebin.com/MBNHAtid << tutaj akurat linia asemblera jest zakomentowana, i jako argument są po prostu bajty tej instrukcji.
0

Możesz printowalnymi instrukcjami zapisywać, albo pisać tylko printowalnymi i odczytywać. link

mwl4
Coś takiego raczej nie da rady.
A1
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 6 lat
  • Postów:10
1

Poszukaj kodu rasm2:

Kopiuj
$ rasm2 -a x86 -b 64 'mov rax, 23; mov rax, [rax]'
48c7c017000000488b00
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:minuta
2
mwl4 napisał(a):

Dodam, że potrzebne mi to tylko do trywialnych instrukcji, typu:

Czy dużo będzie różnych tych „trywialnych” instrukcji?

Bo może wystarczy doczytać/obadać jak wyglądają te instrukcje i generować samemu.

Przykładowo, podane wyżej instrukcje

Kopiuj
mov rcx, rdx
mov rcx, [rsp+0x100]
movq r9, xmm2

to (skompilowane NASMem):

Kopiuj
48 89 D1 48 8B 8C 24 00 01 00 00 66 49 0F 7E D1

co można podzielić na (robię to z głowy):

Kopiuj
48 89 D1
48 8B 8C 24 00 01 00 00
66 49 0F 7E D1

Offset +0x100 z drugiej instrukcji widać na czterech jej ostatnich bajtach (little endian).
Początkowe bajty 48 to prefiksy REX (oznaczające że instrukcja korzysta z nowych rejestrów x64).
Następne 89 i 8B to różne rodzaje mov.
W ostatniej instrukcji prefix 66 oznacza w tym przypadku instrukcję SSE (w przeciwieństwie do MMX), prefix REX 49 że będzie użyty jeden z nowych rejestrów (r9), następnie 0F 7E to zapewne sam movq (instrukcje MMX i SSE zwykle zaczynają się na 0F).
Dodatkowe bajty (D1 w pierwszej i trzeciej, 8C 24 w drugiej) zawierają resztę informacji, czyli użyte rejestry. Tych na pamięć nie znam.

Tyle z głowy bez patrzenia w dokumentację.

edytowany 6x, ostatnio: Azarien
Zobacz pozostałe 2 komentarze
mwl4
No to wariantów jest od cholery przecież. Samego np. mov r_, r_ jest 16*15.
Azarien
to przecież nie mówię żebyś brute-force'em odgadywał każdą instrukcję. od tego jest dokumentacja.
mwl4
No tak, ale właśnie sęk w tym, żeby być może nie wynajdywać koła od nowa, bo jest jakiś tiny assembler x64 który to wszystko już ma. Aktualnie robię coś takiego: http://pastebin.com/MBNHAtid i assembluję tym: https://defuse.ca/online-x86-assembler.htm. Ale dobrze by było to przechowywać w formie stringa i żeby to się samo generowało.
Azarien
pytanie czy faktycznie potrzebny ci asembler, bo może łatwiej generować kod jakiegoś języka skryptowego, np. Lua.
mwl4
Hmm.. ale mi są potrzebne konkretne instrukcje assemblera jako bytecode.
PR
  • Rejestracja:około 11 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Pomorskie (Stare Kabaty)
1

Ja myślę podobnie jak @Azarien.
Spisz potrzebne instrukcje i obadaj bajtowo jak one wyglądają.
Miałem niedawno podobny problem, bo potrzebowałem generować podstawowe instrukcje, to napisałem sobie generator prosty, nawet dokumentacja od intela nie jest potrzebna w 100% bo starczy jakiś doc jak sandpile.org i generowanie kodu nasmem (btw, nasm nie obsługuje adresowania z RIP :/) i sprawdzanie jak sie zmienia pod disassemblerem.
Jednakże potem jak już potrzebowałem złożonych instrukcji, to generowałem sobie NASMem, libka nie była potrzebna mi.
Generalnie generacja podstawowych instrukcji jest dosyć łatwa, także implementacja nie będzie długa. Schody mogą być przy bardziej złożonych.

edytowany 1x, ostatnio: Proxima
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:minuta
4
Proxima napisał(a):

nasm nie obsługuje adresowania z RIP :/

Nieprawda.

Kopiuj
mov eax, [rel dword x]

Przeciwieństwiem rel jest abs. Domyślnie jest abs. Można zmieniać dyrektywą default:

Kopiuj
mov eax, [dword x] ; abs
mov eax, [rel dword x] ; rel

[default rel]

mov eax, [dword x] ; rel
mov eax, [abs dword x] ; abs
edytowany 2x, ostatnio: Azarien
PR
O, faaktycznie :D Dzięki, jak potrzebowałem adresu rel, to się gimnastykowałem z mov eax, [rip] i mi nie łykał tego NASM. To opkody wstawiłem.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)