/NoMagic/Wrappers/FASM.cpp

http://nomagic.googlecode.com/ · C++ · 106 lines · 67 code · 21 blank · 18 comment · 13 complexity · 6e74c41d6152b67a198f3bb2805b6236 MD5 · raw file

  1. /* Copyright (C) 2012 Dennis Garske (a.k.a. Nightblizard)
  2. <http://nightblizard.blogspot.com> <nightblizard@gmail.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "../Wrappers_Include.h"
  15. namespace NoMagic
  16. {
  17. namespace fasm
  18. {
  19. Assembler::Assembler()
  20. {
  21. #ifdef _M_AMD64
  22. throw MagicException(_T("This features is not supported in x64!"));
  23. #endif
  24. this->fasmLib = LoadLibrary("FASM.DLL");
  25. if(this->fasmLib == nullptr)
  26. throw MagicException("Can not load FASM.DLL!", GetLastError());
  27. this->fasm_assemble = reinterpret_cast<tfasm_assemble>(GetProcAddress(this->fasmLib, _T("fasm_Assemble")));
  28. if(this->fasm_assemble == nullptr)
  29. throw MagicException("GetProcAddress(\"fasm_Assemble\") failed!", GetLastError());
  30. auto getVersion = reinterpret_cast<int(_stdcall*)()>(GetProcAddress(this->fasmLib, _T("fasm_GetVersion")));
  31. if(getVersion == nullptr)
  32. throw MagicException("GetProcAddress(\"fasm_Assemble\") failed!", GetLastError());
  33. this->version = getVersion();
  34. }
  35. Assembler::~Assembler()
  36. {
  37. FreeLibrary(this->fasmLib);
  38. }
  39. char* Assembler::toAsm(const char* source, int& outLen) const
  40. {
  41. fasm_read_buffer buffer = {};
  42. int fasm_returnValue = this->fasm_assemble(source, &buffer, sizeof(buffer), 100, nullptr);
  43. if(fasm_returnValue != 0)
  44. throw MagicException("fasm_assemble failed!", fasm_returnValue);
  45. outLen = buffer.state.output_length;
  46. char* retChar = new char[outLen + 1];
  47. memset(retChar, '\0', outLen + 1);
  48. memcpy(retChar, buffer.state.output_data, outLen);
  49. return retChar;
  50. }
  51. std::vector<BYTE> Assembler::Assemble(const std::string& instructions) const
  52. {
  53. auto semicolon = instructions.find(';');
  54. auto code = instructions;
  55. if(semicolon == -1)
  56. throw MagicException("Semicolon is missing!");
  57. std::vector<BYTE> retVector;
  58. do
  59. {
  60. auto substr = code.substr(0, semicolon);
  61. int len = 0;
  62. char* buffer;
  63. MAGIC_CALL( buffer = toAsm(substr.c_str(), len); )
  64. for(int i = 0; i < len; ++i)
  65. {
  66. auto byte = *(reinterpret_cast<BYTE*>(&buffer[i]));
  67. retVector.push_back(byte);
  68. }
  69. delete[] buffer;
  70. code = code.substr(semicolon+1);
  71. semicolon = code.find(';');
  72. } while(semicolon != -1);
  73. return retVector;
  74. }
  75. int Assembler::GetVersion() const
  76. {
  77. return this->version;
  78. }
  79. }
  80. }