[C/C++] Inline-Assembler - API Wrapper

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von cIntX, 3. August 2007 .

Schlagworte:
  1. 3. August 2007
    Inline-Assembler - API Wrapper

    Code:
    #include <map>
    #include <vector>
    using namespace std;
    
    typedef struct {
     char * cszFilename;
     HMODULE hHandle;
    } tDLL;
    std::map<int, tDLL*> pDLL;
    
    int FindFreeHandle() {
     if(pDLL.size() == 0) {
     return 0x01;
     } else {
     return (pDLL.end()->first)+1;
     }
    }
    
    unsigned int API_Wrapper LoadDLL(const char *cszFilename) {
     tDLL * pSubDLL = new tDLL;
     memset(pSubDLL,0,sizeof(tDLL));
     _cprintf("Loading Library\n");
     HMODULE hMod = LoadLibraryA((LPCSTR)cszFilename);
     int handle = FindFreeHandle();
     if(hMod) {
     pSubDLL->cszFilename = new char[strlen(cszFilename)];
     strcpy(pSubDLL->cszFilename, cszFilename);
     _cprintf("File: %s\n", pSubDLL->cszFilename);
     pSubDLL->hHandle = hMod;
     _cprintf("Handle: %u | %u\n", pSubDLL->hHandle, hMod);
     pDLL[handle] = pSubDLL;
     return handle;
     } else {
     return NULL;
     }
    }
    
    void * API_Wrapper CallDLL(unsigned int uHandle, unsigned int uCallConvention, const char *cszFunction, ...) {
     vector<void*> args;
    
     va_list va;
     void * aPointer;
     void * tmpEax;
     int n = 0;
     std::map<int, tDLL*>::iterator itr = pDLL.find((int)uHandle);
     if(itr != pDLL.end()) {
     HMODULE hMod = itr->second->hHandle;
     _cprintf("Calling (%s | %s): %u\n", itr->second->cszFilename, cszFunction, hMod);
     __asm {
     push cszFunction;
     push hMod;
     call dword ptr [GetProcAddress];
     cmp eax,0;
     jz func_end;
     mov tmpEax, eax
     }
     va_start(va, cszFunction);
     printf("Arglist: %p", va);
     if(va) {
     do {
     aPointer = (void*)va_arg(va, void*);
     if(aPointer) {
     args.push_back(aPointer);
     n += 4;
     }
     } while (aPointer);
     }
     va_end(va);
    
     for(int i = args.size(); i = 0; i = i -1) {
     if(args[i] != 0) {
     void * pArg = (void*)args[i];
     __asm {
     push pArg;
     }
     }
     }
     __asm {
     mov eax, tmpEax;
     call eax;
     }
     if(uCallConvention == 0x01) {
     if(n != 0) {
     __asm {
     add esp, n;
     }
     }
     }
     __asm {
    func_end:
     retn;
     }
     } else {
     return NULL;
     }
     return NULL; //Nothing worked?
    }
    
    unsigned int CloseDLL(int uHandle) {
     std::map<int, tDLL*>::iterator itr = pDLL.find((int)uHandle);
     if(itr != pDLL.end()) {
     bool ret = FreeLibrary(itr->second->hHandle);
     pDLL.erase(itr);
     return (int)ret;
     }
     return 0;
    }
    Für C++ Blinde: Confixx

    Wer weiss wieso es abstürzt beim register übergeben ist gut. EAX enthält die richtigen werte aber dan sobald die werte das Programm erreichen das den API aufruf gestartet hat gibts en schönen absturz. Ist es möglich das ich den Stack fahlsch adjustiere eventl. zu viel? Ich blick selbst nicht mehr bei meinen eigenen Code durch. Und ich frag mich obs eine bessere variante gibt unendlich Argumente zu übergeben ohne eine 0 am ende in die Liste zu setzen. Thx im vorraus
     
  2. 3. August 2007
    AW: Inline-Assembler - API Wrapper

    Sry, aber ich glaub da wird dir kaum einer weiterhelfen können...
    Irgendwie ist der Code aber auch total sinnlos und daher die frage: Wofür?

    mfg r90
     
  3. 3. August 2007
    AW: Inline-Assembler - API Wrapper

    Vlt sinnlos für dich. Diese DLL soll dazu führen API aufzurufen ohne eine declaration zu nutzen. Z.b. Visual Basic ist nicht in der lage DLLS zu nutzen ohne die API dafür zu declariert haben. Wen man meine DLL nutzt brauch man das nicht.
     
  4. 3. August 2007
    AW: Inline-Assembler - API Wrapper

    Wie willst die DLL ohne api funktionen laden?
    statisch linken? Dann brauchst die deklarationen für die dll
     
  5. 3. August 2007
    AW: Inline-Assembler - API Wrapper

    Ja weißt du, ich glaub nicht das du das aus VB aus nutzen kannst... v.a. wegen dem VarArg ned...
    Es ist und bleibt sinnlos...

    mfg r90
     
  6. 5. August 2007
    AW: Inline-Assembler - API Wrapper

    Ich glaub ihr wisst einfach nicht worum es sich handlet. Ich habe das programm bis ins letzte detail debugged Argumente sind wie gewohnt im esp pointer, eax wie gewohnt übergabe. DLL's laden ohne Declaration IST möglich. Du solltest dir mal die LoadLibraryA & GetProcAddress functionen anschauen. Du kannst die addresse von GetProcAddress auf eine virtuelle function typecasten und kannst diese funktion per pointer aufrufen und auch alle argumente declarieren.

    In assembly ist zum beispiel NUR der einzige weg LoadLibrary und GetProcAddress
    Code:
    push Filename;
    call LoadLibraryA;
    push ExportName;
    push eax;
    call GetProcAddress
    push argument1
    push argument2
    call eax;
    add esp,8
    retn
    
    so sieht das z.b. in assembly aus
     
  7. 5. August 2007
    AW: Inline-Assembler - API Wrapper

    Ähm, jeder Assembler für Windows hat auch Header und Libs für Windows mit den ganzen Funktionen; man bruachst LoadLibrary sogut wie nie. Und wenn dir Libs fehlen, kann man die auch aus DLL's erstellen lassen. Es ist einfach sinnlos.
     
  8. 5. August 2007
    AW: Inline-Assembler - API Wrapper

    Der Hintergrund ist bei mir gerade folgender: Ich schreibe eine Scripting Engine in Visual Basic 6, ja ich weis das ist normal was für anfänger allerdings benutze ich C++ wirklich nur dan wen nötig. Die Sprache die ich gerade schreibe soll es leuten ermöglichen API aufzurufen ohne weitere declaration. API in Modules linken ist aufwändig und stressig und es gibt zu viel. Auserdem rede ich nicht von direkt Assembly sondern vom Inline-Assembler, es stehen nur die Library zu verfügung die in den "Link Dependencys" dabei sind. LoadLibrary / GetProcAddress soll einfach das nervige declarieren von virtuellen Functionen bei seite lassen und wird dadurch dynamisch.

    typedef HINSTANCE (*fpLoadLibrary)(char*); <-- z.b. nicht Dynamisch, Argumente können nicht mehr verändert werden.

    andernfalls eax als Pointer zu nutzen hat die größte Dynamik, naja falls niemand helfen kann, dann kann man nichts machen.
     
  9. 6. August 2007
    AW: Inline-Assembler - API Wrapper

    Okay, jez versteh ich das ganze...
    Also dein Code sieht eigentlich ganz gut aus, ich erkennt da grad keine Fehler.
    Das einzigste zudem ich dir nichts sagen kann, ist das va_list, evtl liegt ja da der Fehler.
    Und du solltest auch den Rückgabecode handlen, sonst is das ganze wirklich sinnlos^^
     
  10. 6. August 2007
    AW: Inline-Assembler - API Wrapper

    Was soll ich darunter verstehen? Soviel ich weis ist eax üblicher ausgabe register oder irre ich mich? Den wen eax es nicht wäre, dan würde VB auch keine DLLS laden können
     
  11. 8. August 2007
    AW: Inline-Assembler - API Wrapper

    Oh, hab das "retn" übersehen^^ Hab nur das "return NULL" gesehen und dachte mir schon was das denn bringen soll xD ^^

    mfg r90
     
  12. 8. August 2007
    AW: Inline-Assembler - API Wrapper

    ich habs jetzt nich so genau angeschaut, aber ich denke es liegt am stack. wahrscheinlich wird der stack nicht in seinen ursprungszustand versetzt, so wie der c++ code das erwartet. de beste möglichkeit wäre wohl die komplette funktion in asm zu schreiben, dann hast du die volle kontrolle über den stack und die register.

    allerdings kannst dus auch in der form belassen und dafür sorgen, das alles wieder korrekt hergestellt wird, d.h. befor du das erste mal was am stack oder de registern veränderst

    pushad
    mov ebp, esp

    einfügen

    und zum wiederherstellen

    mov esp, ebp
    popad

    vllt hattest du sowas in ähnlicher form schon probiert. wenn es nich hilft, kannst du ja auch mal den OllyDebugger bemühen, da siehst du auch was passiert, und an welcher stelle der fehler auftritt.
     
  13. 8. August 2007
    AW: Inline-Assembler - API Wrapper

    Ich habe mir auch schon überlegt ob es am stack adjustment liegt ich speicher ja jedes mal die 4 bytes sobald ein argument gepushed wird. Eventl sollte ich mal checken wieviel bytes der adjustiert.

    also sprich: add esp,x
     
  14. 14. August 2007
    AW: Inline-Assembler - API Wrapper

    also abstürzen klingt mir auch ganz nach falscher rücksprung adresse.

    hast schonmal die stack adressen bei beginn der funktion und vor dem retn verglichen?

    und an welcher stelle tickt er denn aus, bist das ganze schonmal im debugger schritt für schritt durchgegangen, dann solltest du es ja mehr als sehen^^
     
  15. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.