Archive pour la catégorie ‘Assembleur’

Play with WebAssembly WASM

Lundi 22 janvier 2018

WebAssembly is assmbly in webbrowser. You can run C, C++, other language faster than javascript.

Code Source: wasm.zip

1. Compile Code
Just go to https://wasdk.github.io/WasmFiddle/ type your code, click on build, and download WebAssemenbly binary.

int main() {
return 42;
}

2. Make HTML
Now you can make HTML page like that

fetch('program.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes)
).then(results => {
console.log( results.instance.exports.main() );
});

3. Run
Open you HTML file in your browser and see result.

Gcc et Nasm en 64bit

Samedi 21 décembre 2013

Voici un petit exemple pour creer une fonction en assembleur avec NASM, et ensuit l’utiliser dans un programme C. Attention les convention de passage d’argument en 64bit ne sont plus les meme que pour du 32bits.
Fichier add.asm
global myfunction
section .text

myfunction:
mov eax, edi
mov ecx, esi
add eax, ecx
ret

Fichier test.c
#include

extern int myfunction(int a,int b);

int main()
{
printf("sum=%d\n", myfunction(12,3));
}

Pour compiler :
gcc -c test.c; nasm -f elf64 add.asm; gcc -o add test.o add.o
Le code source: asm

Comment générer un fichier executable

Lundi 17 octobre 2011


La finalité d’un compilateur est de fournir un fichier binaire. Je me suis donc penché sur le cas Windows. Les fichiers « exe » de Microsoft Windows sont nommé PortableExecutable, ou PE. Après une entête il permet de stoker des données et du code binaire exécutable dans un seul fichier.

Nous allons réutilisé le code de l’article du shell-code sous Windows, pour genérer notre fichier. Rien est bien compiler mais il faut remplir des stucts à la main.

[sourcecode language="cpp"]
#include <windows.h>
#include <stdio.h>

void writeEmpty( FILE *file, int size )
{
char empty = ‘\0’ ;
for (int i=0;i<size;i++)
fwrite( &empty, 1, 1, file );
}

int main()
{
int pos = 0;
FILE *file = fopen( "out.exe", "wb" );
IMAGE_DOS_HEADER image_dos_header;
IMAGE_NT_HEADERS image_nt_headers;
IMAGE_OPTIONAL_HEADER& image_optional_header = image_nt_headers.OptionalHeader ;
IMAGE_SECTION_HEADER image_section_header;
char shellcode[] = "\x55\x89\xE5\x6A\x64\x68\xB8\x01\x00\x00\xBB\xA7\x7A\x83\x7C\xFF\xD3\x89\xEC\x5D\xC3";
char dos_str[] = "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68\x69\x73\x20\x70\x72\x30\x67\x72\x61\x6D\x20\x63\x61\x6E\x6E\x30\x74\x20\x62\x65\x20\x72\x75\x6E\x20\x69\x6E\x20\x44\x4F\x53\x20\x6D\x30\x64\x65\x2E\x0D\x0A\x24\x00\x00\x00\x00\x00\x00\x00\x00" ;
memset( &image_dos_header, 0, sizeof(image_dos_header) );
image_dos_header.e_magic = IMAGE_DOS_SIGNATURE ; //0x5A4D ;
image_dos_header.e_cblp = 0×0090 ;
image_dos_header.e_cp = 3 ;
image_dos_header.e_cparhdr = 4 ;
image_dos_header.e_maxalloc = 0xFFFF ;
image_dos_header.e_sp = 0x00B8 ;
image_dos_header.e_lfarlc = 0×0040 ;
image_dos_header.e_lfanew = sizeof(image_dos_header)+sizeof(dos_str)-1;//e_lfanew : Ce champ pointe vers l’entête PE.
fwrite( &image_dos_header, 1, sizeof(image_dos_header), file );
pos += sizeof(image_dos_header);
fwrite( dos_str, 1, sizeof(dos_str)-1, file );
pos += sizeof(dos_str)-1;
memset( &image_nt_headers, 0, sizeof(image_nt_headers) );
image_nt_headers.Signature = IMAGE_NT_SIGNATURE ; //0×00004550 // PE00
image_nt_headers.FileHeader.Machine = 0x014c ; //386
image_nt_headers.FileHeader.NumberOfSections = 1 ;
image_nt_headers.FileHeader.SizeOfOptionalHeader = 0x00E0 ;
image_nt_headers.FileHeader.Characteristics = 0x030F ;
image_optional_header.Magic = 0x010B ;
image_optional_header.MajorLinkerVersion = 0×06 ;
image_optional_header.MinorLinkerVersion = 0×00 ;
image_optional_header.AddressOfEntryPoint = 0×00001000 ;
image_optional_header.BaseOfCode = 0×1000 ;
image_optional_header.SizeOfImage = 0×2000 ;
image_optional_header.ImageBase = 0×00400000 ;
image_optional_header.SectionAlignment = 0×00001000 ;
image_optional_header.FileAlignment = 0×00000200 ;
image_optional_header.MajorOperatingSystemVersion = 0×0004 ;
image_optional_header.MinorOperatingSystemVersion = 0×0000 ;
image_optional_header.MajorSubsystemVersion = 0×0004 ;
image_optional_header.SizeOfHeaders = 0×00000200 ;
image_optional_header.Subsystem = 0×0002 ;
image_optional_header.SizeOfStackReserve = 0×00100000 ;
image_optional_header.SizeOfStackCommit = 0×00001000 ;
image_optional_header.SizeOfHeapReserve = 0×00100000 ;
image_optional_header.SizeOfHeapCommit = 0×00001000 ;
image_optional_header.NumberOfRvaAndSizes = 0×00000010 ;
fwrite( &image_nt_headers, 1, sizeof(image_nt_headers), file );
pos += sizeof(image_nt_headers);
memset( &image_section_header, 0, sizeof(image_section_header) );
strcpy( (char*)(image_section_header.Name), ".idata" );
image_section_header.Misc.VirtualSize = sizeof(shellcode) – 1 ;
image_section_header.VirtualAddress = 0×1000 ;
image_section_header.SizeOfRawData = 0×200 ;
image_section_header.PointerToRawData = 0×200 ;
DWORD d1 = (DWORD)&image_section_header ;
DWORD d2 = (DWORD)&(image_section_header.PointerToRawData) ;
image_section_header.PointerToRawData = 0×200 ;
image_section_header.Characteristics = 0×60000020 ;
fwrite( &image_section_header, 1, sizeof(image_section_header), file );
pos += sizeof(image_section_header);
writeEmpty( file, 0×200 – pos );
fwrite( shellcode, 1, sizeof(shellcode)-1, file );
writeEmpty( file, 0×200-sizeof(shellcode)+1 );
fclose( file );
}
[/sourcecode]

source TinyPE, PE File Format

ShellCode sous windows

Mardi 8 mars 2011

On a vue comment faire un shellcode sour linux, mais maintenant passons sous windows. On va ecrit en premier le code que l’on voudra exécuter, ici on choisi la fonction Beep qui émette un son.

[sourcecode language="c"]
#include <windows.h>
void main()
{
Beep( 440, 100 );
}
[/sourcecode]

Pour le compiler je vous conseille le petit compilateur TCC.

tcc code.c
code.exe

Pour décompiler on peut utiliser OllyDbg, et pour compiler de l’assembleur FASM est très puissant. Donc c’est pas très compliquer d’écrire la correspondance en assembleur.

[sourcecode language="c"]
format    PE console
include ‘win32ax.inc’ ;
start:
push ebp
mov ebp,esp
push 100
push 440
mov ebx, 0x76fa38a9
call ebx
mov esp,ebp
pop ebp
ret
.end start
[/sourcecode]

Bon mais c’est quoi ce 0x76fa38a9 ? Tout les programmes sont au moins liée avec Kernel32.dll, sa tombe bien la fonction Beep est dedans. Mais pour récupérer l’adresse il nous faut un petit programme :arwin.c

tcc arwin.c
arwin kernel32.dll Beep
arwin – win32 address resolution program – by steve hanna – v.01
Beep is located at 0x76fa38a9 in kernel32.dll

Maintenant que l’on a tout on compile l’assembleur et on edit le code soit dans OllyDbg, soit tout simplement dans un éditeur hexadécimal comme HxD. On récupère les bytes correspondant au code, pour écrire ce code :

[sourcecode language="c"]
#include <windows.h>
typedef void (*Func)(void);
int main()
{
char shellcode[] = "\x55\x89\xE5\x6A\x64\x68\xB8\x01\x00\x00\xBB\xA9\x38\xFA\x76\xFF\xD3\x89\xEC\x5D\xC3";
Func func = (Func)shellcode ;
func();
}
[/sourcecode]

[sources]

Shellcode sous linux

Samedi 5 mars 2011

Bon si on arrive a générer du bytecode en Java cela doit bien être possible en code assembleur? C’est même presque plus simple, on appelle même cela un shellcode: un buffer qui contient le code compiler. Cet article est très inspiré du site http://howto.shell-storm.org où tout est très bien expliqué et en français même!

Pour bien appréhendé cet article il vous faut, un linux (ici Ubuntu 10.10), tournant sur un pc x86 32bit (pour un precesseur x64 il faudrai modifier les appels systèmes, pour un processeur ARM tout changer :) )

Donc étape 1, fabrication du shellcode :

[sourcecode language="c"]
xor %eax,%eax #met le registre EAX à zero
mov $29,%al #on met 29 dans al
#29 est l’appel système pour pause
int $0×80 #l’appel system
[/sourcecode]

Donc ce petit bout d’assembleur permet de faire un appel système à la fonction pause. Le 29 est l’identifiant de la fonction pause en x86. Comme cette fonction ne possède pas d’argument cela simplifie l’appel.

On compile :

$ as -o pause.o pause.s

Maintenant on demander le code assembleur du fichier générer mais en plus on aurra la correspondance entre le code assembleur, et les code machine correspondant.

$ objdump -d pause.o

pause.o:     file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0:    31 c0                    xor    %eax,%eax
2:    b0 1d                    mov    $0x1d,%al
4:    cd 80                    int    $0×80

Donc on remarque que 31 correspond à l’opération xor, b0 pour mov… Donc le shell code est 31,c0,b0,1d… Maintenant que l’on a le shellcode il faudrait pourvoir l’exécuter depuis un programme C:

[sourcecode language="c"]
#include <stdio.h>
void main(void)
{
char shellcode[] = "\x31\xc0\xb0\x1d\xcd\x80";
(*(void(*)()) shellcode)();
}[/sourcecode]

Pour la compilation si on fait juste un appel à gcc sans argument on se retrouve avec une erreur de segmentation. En effet, gcc rajoute des instructions permetant de limité la casse, pour continuer il va falloir désactivé ces protections. On compile donc avec la commande:

$ gcc -fno-stack-protector -z execstack -o pausec pause_c.c
$ ./pausec

Et lors de l’exécution le terminal reste bloqué, bon par très exceptionnel comme démo, mais un joli hello world sera pour un autre jour.

Petite application en assembleur

Jeudi 22 mai 2008

Ayant trouver un petit compilateur assembleur extrêmement puissant (FASM), me voila lancer pour développer un petit logiciel en assembleur Win32. Ce logiciel est simple il permet de tracer les connexions à un ordinateur. Si vous rajouter ce logiciel au lancement de la machine il écrira dans un fichier de log, la date et l’heure du démarrage. Si une demande de fermeture de Windows est demandé on log aussi l’heure. Et le petit plus, et que si la session est locké (touche Windows+L) ceci est aussi tracé.


; Simple text editor - fasm example program

format PE GUI 4.0
entry start

include ‘win32a.inc’

IDM_NEW = 101
IDM_EXIT = 102
IDM_ABOUT = 901

section ‘.data’ data readable writeable

_class TCHAR ‘SESSION32′,0
_edit TCHAR ‘EDIT’,0

_title TCHAR ‘Session’,0
_about_title TCHAR ‘About Session’,0
_about_text TCHAR ‘This is Win32 example program created with flat assembler.’,0
_error TCHAR ‘Startup failed.’,0
_error1 TCHAR ‘Unable to open’,0

_text TCHAR ‘Hello’,0
_sessionStart TCHAR ‘Session start’, 0
_sessionStop TCHAR ‘Session stop’, 0
_sessionLock TCHAR ‘Session lock’, 0
_sessionUnlock TCHAR ‘Session unlock’, 0

_file TCHAR ‘session.txt’,0
_dwWritted dd ?
_handle dd ?
_time SYSTEMTIME 0
_buff TCHAR 255 dup(0)
_strFmtDate TCHAR 0x0D, 0x0A, ‘%0.2d/%0.2d/%0.4d ‘,0
_strFmtTime TCHAR ‘%0.2d:%0.2d:%0.2d ‘,0
wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

edithwnd dd ?
editfont dd ?

msg MSG
client RECT

section ‘.code’ code readable executable

start:

invoke GetModuleHandle,0
mov [wc.hInstance],eax
invoke LoadIcon,eax,17
mov [wc.hIcon],eax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
invoke RegisterClass,wc
test eax,eax
jz error

invoke LoadMenu,[wc.hInstance],37
invoke CreateWindowEx,0,_class,_title,WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,[wc.hInstance],NULL
test eax,eax
jz error

;BOOL ret = WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION);
invoke WTSRegisterSessionNotification, eax, 0
test eax,eax
jz error

msg_loop:
invoke GetMessage,msg,NULL,0,0
cmp eax,1
jb end_loop
jne msg_loop
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop

error:
invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

end_loop:
invoke ExitProcess,[msg.wParam]

proc WriteToFile text
invoke CreateFile, _file, GENERIC_READ+GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
mov [_handle], eax
test eax,INVALID_HANDLE_VALUE

;Va a la fin du fichier
invoke SetFilePointer, [_handle], 0, 0, FILE_END

invoke GetSystemTime, _time
movzx ecx,[_time.wYear]
movzx ebx,[_time.wMonth]
movzx eax,[_time.wDay]
invoke wsprintf, _buff, _strFmtDate, eax, ebx, ecx
invoke lstrlen, _buff
invoke WriteFile, [_handle], _buff, eax, _dwWritted, 0

movzx eax,[_time.wHour]
movzx ebx,[_time.wMinute]
movzx ecx,[_time.wSecond]
invoke wsprintf, _buff, _strFmtTime, eax, ebx, ecx
invoke lstrlen, _buff
invoke WriteFile, [_handle], _buff, eax, _dwWritted, 0

invoke lstrlen, [text]
invoke WriteFile, [_handle], [text], eax, _dwWritted, 0

or eax,eax
jz error1

invoke CloseHandle, [_handle]
ret
error1:
invoke MessageBox,NULL,_error1,NULL,MB_ICONERROR+MB_OK
ret
endp

proc WindowProc hwnd,wmsg,wparam,lparam
push ebx esi edi
cmp [wmsg],WM_CREATE
je .wmcreate
cmp [wmsg],WM_QUERYENDSESSION
je .wmqueryendsession
cmp [wmsg],WM_DESTROY
je .wmdestroy
cmp [wmsg],0x02B1 ;WM_WTSSESSION_CHANGE
je .wmsessionchange

.defwndproc:
invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp .finish

.wmcreate:
; Ecrire dans le fichier
stdcall WriteToFile, _sessionStart
jmp .finish

.wmqueryendsession:
; Ecrire dans le fichier
stdcall WriteToFile, _sessionStop
jmp .wmdestroy ; On quit

.wmsessionchange:
mov eax, [wparam]
and eax, 0×7 ;WTS_SESSION_LOCK
jnz .sessionlock
mov eax, [wparam]
and eax, 0×8 ;WTS_SESSION_UNLOCK
jnz .sessionunlock
jmp .finish
.sessionlock:
stdcall WriteToFile, _sessionLock
jmp .finish
.sessionunlock:
stdcall WriteToFile, _sessionUnlock
jmp .finish

.wmdestroy:
invoke WTSUnRegisterSessionNotification, [hwnd]
invoke PostQuitMessage,0
xor eax,eax

.finish:
pop edi esi ebx
ret
endp

section ‘.idata’ import data readable writeable

library kernel,’KERNEL32.DLL’,\
user,’USER32.DLL’,\
gdi,’GDI32.DLL’,\
WtsApi,’WtsApi32.DLL’

import WtsApi,\
WTSRegisterSessionNotification, ‘WTSRegisterSessionNotification’,\
WTSUnRegisterSessionNotification, ‘WTSUnRegisterSessionNotification’

import kernel,\
GetModuleHandle,’GetModuleHandleA’,\
ExitProcess,’ExitProcess’,\
CreateFile,’CreateFileA’,\
CloseHandle,’CloseHandle’,\
WriteFile,’WriteFile’,\
SetFilePointer,’SetFilePointer’,\
GetSystemTime,’GetSystemTime’,\
lstrlen,’lstrlen’

import user,\
RegisterClass,’RegisterClassA’,\
CreateWindowEx,’CreateWindowExA’,\
DefWindowProc,’DefWindowProcA’,\
SetWindowLong,’SetWindowLongA’,\
RedrawWindow,’RedrawWindow’,\
GetMessage,’GetMessageA’,\
TranslateMessage,’TranslateMessage’,\
DispatchMessage,’DispatchMessageA’,\
SendMessage,’SendMessageA’,\
LoadCursor,’LoadCursorA’,\
LoadIcon,’LoadIconA’,\
LoadMenu,’LoadMenuA’,\
GetClientRect,’GetClientRect’,\
MoveWindow,’MoveWindow’,\
SetFocus,’SetFocus’,\
MessageBox,’MessageBoxA’,\
PostQuitMessage,’PostQuitMessage’,\
wsprintf,’wsprintfA’

import gdi,\
CreateFont,’CreateFontA’,\
DeleteObject,’DeleteObject’

section ‘.rsrc’ resource data readable

; resource directory

directory RT_MENU,menus,\
RT_ICON,icons,\
RT_GROUP_ICON,group_icons,\
RT_VERSION,versions

; resource subdirectories

resource menus,\
37,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu

resource icons,\
1,LANG_NEUTRAL,icon_data

resource group_icons,\
17,LANG_NEUTRAL,main_icon

resource versions,\
1,LANG_NEUTRAL,version

menu main_menu
menuitem ‘&File’,0,MFR_POPUP
menuitem ‘&New’,IDM_NEW
menuseparator
menuitem ‘E&xit’,IDM_EXIT,MFR_END
menuitem ‘&Help’,0,MFR_POPUP + MFR_END
menuitem ‘&About…’,IDM_ABOUT,MFR_END

icon main_icon,icon_data,’minipad.ico’

versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLA