Showing posts with label coding. Show all posts
Showing posts with label coding. Show all posts

Thursday, 29 November 2012

[ASM] How to use the windows API in NASM

Hellooow everybody! ;-)

Today I will give you a short guide on how to use windows API in ASM programming! (at least in programs compiled with NASM because this is the one I'm using and as I'm quite noob about the different versions of asm, I prefer not risk to tell wrong things) This is because I wanted to learn some asm stuff and make little programs on windows, and quickly realized that windows was too protected to use pure asm and that we need to use the windows C++ API, including console I/O.

What is the windows API?
It's a library of C++ functions. You have to use it if you want to make any program on windows. So that means you will have to call these functions in your asm code.
It's called kernel32.dll for 32bits systems, and normally it's in the path :-)
Here is the official documentation:
Here is the documentation for console stuff:

How to call a windows API function in asm?
1) Don't forget the header!
You have to declare any function you want to use in your code by specifying them as external functions. Basically at this point all you have to do is to put a line like this in the begining of your file:
  extern    Function1Name, Function2Name, FunctionNName
example (console I/O):
  extern    ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

/!\ If you want to use any windows constant in the function calls, you also have to declare those.
For example for the GetStdHandle, these can come in handy :
  STD_OUTPUT_HANDLE    equ -11
  STD_INPUT_HANDLE     equ -10
But of course you can directly pass the constant value as an argument (if you wanna do it in the hardcore way :p) 

2) Function calls in asm
Function calls in asm aren't really more complicated than in any other language. You just have to pass the arguments the function needs and call the function's name.
In asm your pass the arguments by pushing them on top of the stack:
  push    arg

/!\ Always remember that as the stack goes decreasing, (unlike a stack of papers) you have to pass the arguments in the reverse order:
  push    arg3
  push    arg2
  push    arg1

Once all the arguments are sent to the stack, you can call the function:
  call    function

Example: WriteConsole call
  push    NULL
  push    buffer_out
  push    msg.len
  push    msg
  push    dword[handleOut]
  call    WriteConsoleA

How to compile and link a program that uses win API functions? (using nasm and golink)
This is the easy part! Just open a console and eventually cd in the right directory.
To compile, type something like:
>> nasm -f win32 yourProgram.asm -o yourProgram.obj
and to link the library using golink:
>> GoLink.exe /console /entry starting_point_of_your_asm_program yourProgram.obj kernell32.dll

Or, you can do a makefile:
  yourProgram: yourProgram.obj
  GoLink.exe /console /entry starting_point_of_your_asm_program yourProgram.obj kernell32.dll
  yourProgram.obj: yourProgram.asm 
  nasm -f win32 yourProgram.asm -o yourProgram.obj

NB: 
If you don't already know GoLink, it's a linker, which means it's able to link your file with the libraries you want. (in this case the kernel32.dll file)
You can download it here: (direct download of last version)
Manual:

NB2:
In order to use these commands, the source folders for nasm and GoLink.exe have to be in the path. So when you install them don't forget to add these at the end of the path variable. (right click on computer => advanced system parameters => environment variables... => find "path" in the system variables table, hit "modify" and add your new paths at the end, separated by a ';')

Working example: system("pause")
  STD_OUTPUT_HANDLE   equ -11
  STD_INPUT_HANDLE    equ -10
  NULL                equ 0
  global start
  extern ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

  section .data    ;message we want to display on console
  msg                 db "Press a key to continue...", 13, 10, 0
  msg.len             equ $ - msg
  consoleInHandle     dd 1

  section .bss     ;buffers declaration
  buffer_out          resd 2
  buffer_in           resb 32

  section .text
    start:       ;starting point of our program
        push    STD_OUTPUT_HANDLE
        call    GetStdHandle   ;call to get a handle to the
        push    NULL           ;specified mode (input, output...)
        push    buffer_out
        push    msg.len
        push    msg
        push    eax            ;contains the GetStdHandle result
        call    WriteConsoleA  ;call to print our msg in console

    read:
        push    STD_INPUT_HANDLE
        call    GetStdHandle        ;new call to get input handle
        push    NULL
        push    1
        push    buffer_in
        push    eax
        call    ReadConsoleInputA   ;call to detect user input
                                    ;this function will wait til
    exit:                           ;it detects enough keypresses
        push    NULL                ;(in this case, 1)
        call    ExitProcess

Manual pages for the functions used in this code:
- ExitProcess
- GetStdHandle
- WriteConsole (A stands for ANSI version)
- ReadConsoleInput (A stands for ANSI version)


I hope this helped some of you! See ya around and have fun coding ;-)


Additional source for this article:
This thread I posted on stackoverflow.com when I was having a hard time understanding all this: ;-p

Wednesday, 15 February 2012

MySQL error 1064 on Jobeet day 3



Voici le fix pour une erreur mysql sur laquelle je me suis arrachée les cheveux pendant deux jours (donc je la met sur le blog pour rentabiliser :p):
C'est sur le tutoriel Symfony Jobeet (qu'on est sensés terminer en moins de 24h d'après la pub), au jour 3 : en mode console, on nous demande de créer des tables dans une base de données à partir d'un fichier YAML.
Plus précisément, on nous demande de générer du sql et de l’exécuter dans la base en utilisant l'outil ORM propel.
Encore plus précisément, cela consiste à taper deux lignes dans l'invite de commande :

>> symfony propel:build-sql
>> symfony propel:insert-sq

...et de laisser faire le pc faire tout le boulot. En théorie. Sauf qu'en fait ça marche pas dans tous les cas ! Voilà le message d'erreur qui est apparu dans mes cauchemars :



Après des heures de prise de tête et de questionnement philosophique ( --et si je devenais pas facteur au lieu de développeur finalement ?) j'ai fini par déterrer un post unique sur internet résolvant le problème...


...que je relaie ici :)


Voilà la marche à suivre :

1. Ouvrez votre fichier MysqlDDLBuilder.php, localisé vers :
symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php
2. A la ligne 156 changez :
$script .= "Type=$mysqlTableType";
en :
$script .= "Engine=$mysqlTableType";
3. N'oubliez pas de vider le cache symfony :
>> symfony cc
4. Et ça marche !!!


Petites explications :

Comme vous avez pu le constater en empruntant le chemin ci-dessus, le problème vient de propel. Si vous êtes confrontés à cette erreur, c'est parce que vous utilisez la version 1 de propel qui a certaines incompatibilités avec mysql, comme celle à laquelle nous avons fait face.
Contrairement à ce qui est indiqué dans le deuxième post (voir lien), je n'ai pas upgradé propel car l'environnement de travail dans mon entreprise utilise exclusivement propel 1. Si vous ne devez pas faire face à ce genre de considérations il est effectivement préférable d'upgrader propel à sa version 1.5... en théorie. Si vous n'avez pas PEAR et que vous êtes pressés ça risque d'apporter son lot d'arrachage de cheveux supplémentaire.
(symfony installe ses plugins grâce à PEAR, qui n'est pas inclus d'office dans la version 1.2 du framework. Et si vous voulez l'installer, malgré le "Install pear is not complicated" dans le readme, ça se fait en mode console, plus il faut tripoter les variables d'environnement... enfin bref on a plus vite fait d'utiliser la méthode rapide et c'est meilleur pour la santé capillaire)