Skip to content

Commit

Permalink
Unicorn 2.x support (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
dargueta authored Apr 17, 2023
1 parent 70da3f0 commit 75e7187
Show file tree
Hide file tree
Showing 26 changed files with 671 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ root = true
charset = utf-8
indent_style = space

[*.{cpp,h,lua,py,template,rst}]
[*.{cpp,hpp,lua,py,template,rst}]
end_of_line = lf
indent_size = 4
insert_final_newline = true
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs:
- "5.4"
- "luajit-2.0.5"
- "luajit-2.1.0-beta3"
unicorn-version:
- "1.0.3"
- "2.0.1"
steps:
- uses: actions/checkout@v3
- name: Install Lua
Expand All @@ -31,7 +34,7 @@ jobs:
# https://github.com/leafo/gh-actions-luarocks/pull/14 has been merged.
uses: hishamhm/gh-actions-luarocks@5013277f6f115c27478f18c1f647f8de98390628
- name: Install Unicorn
run: make -C tools/ci install_unicorn UNICORN_VERSION=1.0.2
run: make -C tools/ci install_unicorn UNICORN_VERSION=${{ matrix.unicorn-version }}
- name: Environment
run: luarocks config
- name: Install Binding
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ tests/c/doctest.h

# Autogenerated files:
src/constants/
src/basic_control_functions.cpp
src/registers.cpp
src/registers_const.cpp
include/unicornlua/register_types.hpp
Expand Down
74 changes: 69 additions & 5 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,21 +1,85 @@
Changes
=======

2.2.0 (Unreleased)
2.2.0 (2023-04-17)
------------------

New Features
~~~~~~~~~~~~

Official support for LuaJIT 2.1.
* Added support for LuaJIT 2.1.
* Added support for Unicorn 2.

Instead of throwing an error ``unicorn.arch_supported()`` now returns false if
the given architecture is nil. This allows code to easily determine if an
architecture is supported without needing to check the Unicorn version AND assume
that the Unicorn library was compiled with all available architectures. For
example:

Old way:

.. code-block:: lua
local have_ppc
if uc:version()[1] < 2 then
have_ppc = false
else
have_ppc = uc.arch_supported(uc_const.UC_ARCH_PPC)
end
New way:

.. code-block:: lua
local have_ppc = uc.arch_supported(uc_const.UC_ARCH_PPC)
See `Unicorn's changelog <https://github.com/unicorn-engine/unicorn/blob/master/ChangeLog>`_
for the details of API changes, but a summary here:

Control Functions
*****************

All ``uc_ctl_*`` macros are their own methods on an engine, minus the ``uc_``
prefix. For libraries linked to Unicorn 1.x these functions are present, but
will throw an exception if used.

**The bare ``uc_ctl()`` function is not exposed.**

Instruction Hooks
*****************

* x86: CPUID (SYSENTER and SYSCALL were broken before and have been fixed)
* AArch64: MRS, MSR, SYS, SYSL

Other Hooks
***********

See the Unicorn documentation for what these do.

* ``UC_HOOK_EDGE_GENERATED``
* ``UC_HOOK_TCG_OPCODE``

Bugfixes
~~~~~~~~

Added missing hook for x86 SYSENTER and SYSCALL instructions. Before, it used
to call the default instruction hook function, which resulted in a segfault
because the wrong number of arguments were getting passed. Since this never
worked from the beginning, I don't consider this a breaking change.

``unicorn.arch_supported()`` now checks the first argument given instead of the
last argument. It's only supposed to take one argument, so if used correctly
this changes nothing. If additional arguments are passed (such as mode flags),
this will now ignore them.

Other Changes
~~~~~~~~~~~~~

* Add clang-format, use WebKit's style (more or less).
* Autogenerate a bunch of register-related files from templates. **Note:** Some
register type enums values have changed. If you use the symbolic constants
provided in ``registers_const`` this won't affect you.
* Autogenerate a bunch of files from templates to reduce duplicated code.

**Note:** Some register type enum values have changed. If you use the symbolic
constants provided in ``unicorn.registers_const`` this won't affect you.

2.1.0 (2023-04-08)
------------------
Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ TEST_LUA_SOURCES = $(wildcard tests/lua/*.lua)
TEST_HEADERS = $(wildcard tests/c/*.hpp)
TEST_CPP_OBJECT_FILES = $(TEST_CPP_SOURCES:.cpp=.$(OBJ_EXTENSION))

TEMPLATE_DATA_FILES = $(wildcard src/template_data/*.lua)

LIBRARY_DIRECTORIES := $(strip $(LUA_LIBDIR) $(FALLBACK_LUA_LIBDIR) $(UNICORN_LIBDIR) $(PTHREAD_LIBDIR) /usr/lib64 /usr/local/lib)
HEADER_DIRECTORIES := $(strip $(CURDIR)/include $(LUA_INCDIR) $(FALLBACK_LUA_INCDIR) $(UNICORN_INCDIR))
HEADER_DIRECTORIES := $(strip $(CURDIR)/include $(LUA_INCDIR) $(FALLBACK_LUA_INCDIR) $(UNICORN_INCDIR) /usr/local/include)

USER_CXX_FLAGS ?=
OTHER_CXXFLAGS := -std=c++11 -DIS_LUAJIT=$(IS_LUAJIT)
Expand Down Expand Up @@ -186,12 +188,12 @@ src/%.$(OBJ_EXTENSION): src/%.cpp $(AUTOGENERATED_HPP_FILES)
$(CXX_CMD) $(CXXFLAGS) -c -o $@ $<


%.cpp: %.template src/register_types.lua
%.cpp: %.template $(TEMPLATE_DATA_FILES)
@echo "Generating $@"
@$(SET_SEARCH_PATHS); $(LUA) tools/render_template.lua -o $@ $^


%.hpp: %.template src/register_types.lua
%.hpp: %.template $(TEMPLATE_DATA_FILES)
@echo "Generating $@"
@$(SET_SEARCH_PATHS); $(LUA) tools/render_template.lua -o $@ $^

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ unicorn-lua
:alt: Build status
:target: https://travis-ci.com/dargueta/unicorn-lua

.. |lua-versions| image:: https://img.shields.io/badge/lua-5.1%20%7C%205.2%20%7C%205.3%20%7C%205.4%20%7C%20LuaJIT2.020%7C%20LuaJIT2.1-blue-blue
.. |lua-versions| image:: https://img.shields.io/badge/lua-5.1%20%7C%205.2%20%7C%205.3%20%7C%205.4%20%7C%20LuaJIT2.0%20%7C%20LuaJIT2.1-blue
:alt: Lua versions
:target: https://www.lua.org

Expand Down
86 changes: 86 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,67 @@ constants for these error codes are in the ``unicorn`` namespace and begin with
``UC_ERR_``.


``ctl_exits_disable()``
~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_exits_enable()``
~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_flush_tlb()``
~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_arch()``
~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_cpu_model()``
~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_exits()``
~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_exits_cnt()``
~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_mode()``
~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_page_size()``
~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_get_timeout()``
~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_remove_cache(start_addr, end_addr)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_request_cache(address)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_set_cpu_model(model)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_set_exits(exits)``
~~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*

``ctl_set_page_size(page_size)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*New in 2.2.0 (requires Unicorn 2)*


``hook_add(kind, callback, start_address=nil, end_address=nil, udata=nil, ...)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -446,6 +507,31 @@ Arguments
``architecture``: An enum value for the architecture to ask about. Constants are
in the ``unicorn`` namespace and begin with ``UC_ARCH_``.

*Changed in 2.2.0:*

``unicorn.arch_supported`` now returns false if the architecture is nil instead
of crashing. This allows code to easily determine if an architecture is supported
without needing to check the Unicorn version AND assume that the Unicorn library
was compiled with all available architectures. For example:

Old way:

.. code-block:: lua
local have_ppc
if uc:version()[1] < 2 then
have_ppc = false
else
have_ppc = uc.arch_supported(uc_const.UC_ARCH_PPC)
end
New way:

.. code-block:: lua
local have_ppc = uc.arch_supported(uc_const.UC_ARCH_PPC)
Returns
^^^^^^^

Expand Down
2 changes: 1 addition & 1 deletion include/unicornlua/compat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ LUALIB_API void lua_rawsetp(lua_State* L, int index, const void* p);
#ifndef luaL_newlib
#define luaL_newlib(L, l) \
(luaL_newlibtable((L), (l)), luaL_setfuncs((L), (l), 0))
#endif // luaL_newlib
#endif // luaL_newlib
#endif // LUA_VERSION_NUM < 502

// http://lua-users.org/lists/lua-l/2011-11/msg01149.html
Expand Down
41 changes: 41 additions & 0 deletions include/unicornlua/control_functions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <unicorn/unicorn.h>

#include "lua.hpp"

[[noreturn]] int ul_crash_unsupported_operation(lua_State* L);

#if UC_API_MAJOR >= 2
int ul_ctl_exits_disable(lua_State* L);
int ul_ctl_exits_enable(lua_State* L);
int ul_ctl_flush_tlb(lua_State* L);
int ul_ctl_get_arch(lua_State* L);
int ul_ctl_get_cpu_model(lua_State* L);
int ul_ctl_get_exits(lua_State* L);
int ul_ctl_get_exits_cnt(lua_State* L);
int ul_ctl_get_mode(lua_State* L);
int ul_ctl_get_page_size(lua_State* L);
int ul_ctl_get_timeout(lua_State* L);
int ul_ctl_remove_cache(lua_State* L);
int ul_ctl_request_cache(lua_State* L);
int ul_ctl_set_cpu_model(lua_State* L);
int ul_ctl_set_exits(lua_State* L);
int ul_ctl_set_page_size(lua_State* L);
#else
#define ul_ctl_exits_disable ul_crash_unsupported_operation
#define ul_ctl_exits_enable ul_crash_unsupported_operation
#define ul_ctl_flush_tlb ul_crash_unsupported_operation
#define ul_ctl_get_arch ul_crash_unsupported_operation
#define ul_ctl_get_cpu_model ul_crash_unsupported_operation
#define ul_ctl_get_exits ul_crash_unsupported_operation
#define ul_ctl_get_exits_cnt ul_crash_unsupported_operation
#define ul_ctl_get_mode ul_crash_unsupported_operation
#define ul_ctl_get_page_size ul_crash_unsupported_operation
#define ul_ctl_get_timeout ul_crash_unsupported_operation
#define ul_ctl_remove_cache ul_crash_unsupported_operation
#define ul_ctl_request_cache ul_crash_unsupported_operation
#define ul_ctl_set_cpu_model ul_crash_unsupported_operation
#define ul_ctl_set_exits ul_crash_unsupported_operation
#define ul_ctl_set_page_size ul_crash_unsupported_operation
#endif
17 changes: 17 additions & 0 deletions include/unicornlua/transaction.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <unicorn/unicorn.h>
#if UC_API_MAJOR >= 2

#include "unicornlua/lua.hpp"

/**
* Create a Lua table representation of a transaction block and push it to the
* Lua stack.
*
* @param L
* @param block
*/
void create_table_from_transaction_block(lua_State* L, const uc_tb* block);

#endif // UC_API_MAJOR
4 changes: 0 additions & 4 deletions include/unicornlua/unicornlua.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
#include "unicornlua/compat.hpp"
#include "unicornlua/lua.hpp"

#if UC_VERSION_MAJOR != 1
#error "Library must be compiled against version 1.x of Unicorn."
#endif

/**
* The major version number of this Lua library (first part, 1.x.x).
*/
Expand Down
2 changes: 1 addition & 1 deletion include/unicornlua/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @note Like lua_error, this function never returns, and should be treated in
* exactly the same way.
*/
int ul_crash_on_error(lua_State* L, uc_err error);
[[noreturn]] void ul_crash_on_error(lua_State* L, uc_err error);

/**
* Create a new weak table with the given key mode, and push it onto the stack.
Expand Down
Loading

0 comments on commit 75e7187

Please sign in to comment.