unerwartetes Runden
-
Hallo zusammen.
Ich habe ein kleines Programm schreiben wollen, dass zwei Zahlen addieren/subtrahieren oder was auch immer kann, allerdings auf die "selbstmodifizierende" Art, also das der Programmcode während der Ausführung sich selber verändert:
#include <string> #include <vector> #include <iostream> #include <cstdlib> using namespace std; template<typename ReturnValue, typename Arg1, typename Arg2 /* ... */> ReturnValue execute(vector<char> opcodes, const Arg1& arg1, const Arg2& arg2) { char* exec = (char*)malloc(1); for(unsigned int i=0; i<opcodes.size(); ++i) exec[i] = opcodes[i]; return ((ReturnValue(*)(Arg1, Arg2))exec)(arg1, arg2); } // Generiert die Opcodes für eine Additionsfunktion. vector<char> add() { vector<char> tmp; // fld [esp+4] tmp.push_back(0xD9); // Koprozessor-Escape tmp.push_back(0x44); // Modulo r/m-Byte tmp.push_back(0x24); // SIB tmp.push_back(0x04); // index // fadd [esp+8] tmp.push_back(0xD8); // Koprozessor-Escape tmp.push_back(0x44); // Modulo r/m-Byte tmp.push_back(0x24); // SIB tmp.push_back(0x08); // index // ret tmp.push_back(0xC3); return tmp; } int main() { cout << "2.5 + 4.8 = " << execute<float, float, float>(add(), 2.5, 4.5) << endl; return 0; }Das funktioniert soweit auch recht gut, allerdings ist die Ausgabe 2.5 + 4.5 = 7, ich wollte aber eigentlich 2.5 + 4.8 = 7.3 ausgegeben bekommen.
Wo liegt der Fehler?Vielen Dank für die Hilfe,
npf.
-
Kann mir wirklich keiner sagen was ich falsch gemacht habe

-
Dann schreib es so:
... cout << "2.5 + 4.8 = " << execute<float, float, float>(add(), 2.5, 4.8) << endl; ...
-
genau das habe ich gemacht.
-
npf schrieb:
genau das habe ich gemacht.
Und wieso steht dann da shier in deinem Quelltext?
cout << "2.5 + 4.8 = " << execute<float, float, float>(add(), 2.5, 4.5) << endl;
-
Zusätzlich sollte auch der markierten Zeile eine besondere Beachtung zukommen.

template<typename ReturnValue, typename Arg1, typename Arg2 /* ... */> ReturnValue execute(vector<char> opcodes, const Arg1& arg1, const Arg2& arg2) { char* exec = (char*)malloc(1); // !!!!!!!!!!!!!!!!!!!!!!!!! for(unsigned int i=0; i<opcodes.size(); ++i) exec[i] = opcodes[i]; return ((ReturnValue(*)(Arg1, Arg2))exec)(arg1, arg2); }
-
So, ich hab jetzt auch erkannt, wo ich mich vertippt hab. Tschuldigung für den blöden Fehler.
Das mit dem malloc(1) geht schon, auch wenns nicht so fein aussieht. Sonst hätte ich mmap unter Linux, VirtualAlloc unter Windows usw. verwenden müssen.Aber trotzdem Dankeschön!
npf.
-
npf schrieb:
Das mit dem malloc(1) geht schon, auch wenns nicht so fein aussieht.
Tschuldige. Mein Fehler. Ich hatte nicht bedacht, dass du sicher irgendwie dafür gesorgt hast, dass hinter exec[0] nichts wichtiges steht und du deshalb garantieren kannst, dass dein Programm nicht absäuft.

Übrigens ist die ganze Kopieraktion sinnlos, weil die Opcodes im Vector ja bereits in der richtigen Reihenfolge vorhanden sind. Statt dem Gefummel mit exec würde auch &opcodes[0] reichen.
-
Abgesehen davon, dass der Speicher nicht mehr freigegeben wird.
-
... und dir malloc / vector im Allgemeinen keinen ausführbaren Speicher zur Verfügung stellt
-
Superlexx schrieb:
... ausführbaren Speicher
Das müsstest du nochmal erklären ...
-
Es ist auf machen Plattformen so, dass es Speicher gibt, der zwar les- und beschreibbar ist, aber sobald man versucht, ein in diesem Speicher liegendes Stück Programm auszuführen, man eine Exception bekommt. Zu solchen Plattformen gehört z.B. Windows XP SP2 und später, wenn sie auf halbwegs aktuellen CPUs laufen, das nennt sich dann DEP.
Und solcher Speicher wird dann im Allgemeinen von new bzw. malloc alloziert (gibt auch Ausnahmen, siehe NXCOMPAT). Wenn man ausführbaren Speicher allozieren möchte, dann muss das mit plattformspezifischen Mitteln geschehen, etwa VirtualAlloc + VirtualProtect unter Windows XP etc.
-
Gut erklärt!
An npfs Beispiel sieht man, was selbst bei einer vermeintlich leichten Aufgabe alles schief gehen kann.

Mehr dazu und warum es mit Standardeinstellungen auch unter XP2 meist doch klappt findet sich in dem Dokument
03_CIF_Memory_Protection.DOC
unter
http://www.microsoft.com/downloads/details.aspx?FamilyID=7bd948d7-b791-40b6-8364-685b84158c78