Skip to content

Commit

Permalink
[WIP] Convert Bash scripts to Python #147 (#338)
Browse files Browse the repository at this point in the history
* Convert most Bash scripts to Python

* Port cmake/install-share to python

* Some cleanup

* Replaced install-share in cmake file with fully working python version

* Attemp to fix compile error

* Fix compile for older python version

* Try calling python 3 instead

* Make install-share.py executable
Compilable decompiler version

* Decompiler script now runs successfully until unpacking

* Running until calling bin2llvmir now

* [skip ci] Integrate @silverbacknet changes + some fixes

* [skip ci] Use CmdRunner.run_cmd everywhere in retdec_decompiler
Small fixes and cleanup
Early out if an error occurs

* [skip ci] Latest fixes
add retdec_tests_runner.py

* [skip ci] Check that options are correct + cleanup and fixes

* [skip ci] Fixed various errors

* Try to fix running install-share script

* Should now work on every os

* Fix compile error

* Convert compile-yara to python

* [skip ci] Make test runner more portable

* [skip ci] Use correct code style

* [skip ci] Decompiler script now runs successfully

* Now generates the same output as the bash script

* Try fixing Travis on macOS

* Upgrade python instead

* Test scripts in travis

* Fix build

* Fix path

* Update build
Small cleanup

* Fix error in decompiler script

* Try to debug failure reason
Fix test runner
Use Python 3.5 on ubuntu

* Use newer Python version and fix some errors

* [skip ci] Little cleanup to make the code more clear
Don't parse_args twice

* [skip ci] First version of reimplementing logging

* [skip ci] Some fixes and cleanup

* [skip ci] Print memory usage, print output from unpacker, match code convention and some other fixes

* [skip ci] Fix crash when using cleanup option; fix crash when using color ida

* [skip ci] Fix --backend-aggressive-opts argument

* [skip ci] Fix error when file arch is followed by a comment

* [skip ci] Match Bash script more closely

* [skip ci] Fix a few comments

* [skip ci] Add some comments

* [skip ci] Add early type_extractor/gen_cstdlib_and_linux_jsons.py and type_extractor/gen_windows_and_windrivers_jsons.py version

* Try Unit tests

* Try to fix test

* Use absolute path instead

* [skip ci] Add check for python scripts

* scripts/retdec_decompiler.py: use output if specified via -o option
  • Loading branch information
TheCodez authored and PeterMatula committed Jul 12, 2018
1 parent 386abd5 commit 4de4f49
Show file tree
Hide file tree
Showing 15 changed files with 3,225 additions and 12 deletions.
16 changes: 8 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ matrix:
addons:
apt:
sources:
- deadsnakes
- ubuntu-toolchain-r-test
packages:
- build-essential
Expand All @@ -19,7 +20,7 @@ matrix:
- g++-4.9
- cmake
- perl
- python3
- python3.5
- flex
- bison
- autoconf
Expand Down Expand Up @@ -55,7 +56,9 @@ install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install gnu-getopt; fi
# bash 4
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install bash; fi

# python 3
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew upgrade python; fi

before_script:
- eval "${MATRIX_EVAL}"
# We need to use newer versions of Flex and Bison on MacOS X (the ones from Homebrew).
Expand All @@ -79,18 +82,15 @@ script:
- cd ..
- rm -rf build
# Run unit tests.
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-tests-runner.sh; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-tests-runner.sh; fi
- python3 retdec-install/bin/retdec_tests_runner.py
# Run the decompilation script.
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-decompiler.sh --help; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-decompiler.sh --help; fi
- python3 retdec-install/bin/retdec_decompiler.py --help
# Run a simple decompilation.
- echo -e '#include <stdio.h>\n#include <stdlib.h>\nint main()\n{\n printf("hello world\\n");\n return 0;\n}\n' > hello-orig.c
- cat hello-orig.c
- gcc -m32 -o hello hello-orig.c
- ./hello
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then /usr/local/bin/bash retdec-install/bin/retdec-decompiler.sh hello; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then ./retdec-install/bin/retdec-decompiler.sh hello; fi
- python3 retdec-install/bin/retdec_decompiler.py hello
- cat hello.c
- grep "int main(int argc, char \*\* argv)" hello.c

Expand Down
16 changes: 12 additions & 4 deletions cmake/install-external.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
install(CODE "
execute_process(
COMMAND sh \"${CMAKE_SOURCE_DIR}/cmake/install-share.sh\" \"${CMAKE_INSTALL_PREFIX}\"
RESULT_VARIABLE INSTALL_SHARE_RES
)
if (WIN32)
execute_process(
COMMAND py -3 \"${CMAKE_SOURCE_DIR}/cmake/install-share.py\" \"${CMAKE_INSTALL_PREFIX}\"
RESULT_VARIABLE INSTALL_SHARE_RES
)
else()
execute_process(
COMMAND python3 \"${CMAKE_SOURCE_DIR}/cmake/install-share.py\" \"${CMAKE_INSTALL_PREFIX}\"
RESULT_VARIABLE INSTALL_SHARE_RES
)
endif()
if(INSTALL_SHARE_RES)
message(FATAL_ERROR \"RetDec share directory installation FAILED\")
endif()
Expand Down
115 changes: 115 additions & 0 deletions cmake/install-share.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3

"""
Get RetDec share directory.
"""
import sys
import hashlib
import os
import shutil
import tarfile
import urllib.request

# Check arguments.
if len(sys.argv) != 2:
print('ERROR: Unexpected number of arguments.')
sys.exit(1)

###############################################################################

version_filename = 'version.txt'
arch_suffix = 'tar.xz'

sha256hash_ref = 'b54ba07e2f28143c9afe34a9d5b4114fb61f3c1175b9807caced471fec82001e'
version = '2018-02-08'

###############################################################################

arch_name = 'retdec-support' + '_' + version + '.' + arch_suffix

# Get install path from script options.
install_path = sys.argv[1]

share_dir = os.path.join(install_path, 'share')
share_retdec_dir = os.path.join(share_dir, 'retdec')
support_dir = os.path.join(share_retdec_dir, 'support')

arch_path = os.path.join(support_dir, arch_name)


###############################################################################

def cleanup():
if os.path.exists(support_dir):
for n in os.listdir(support_dir):
p = os.path.join(support_dir, n)
if os.path.isdir(p):
shutil.rmtree(p)
else:
os.unlink(p)


# Share directory exists.
if os.path.exists(support_dir):
# Version file exists.
if os.path.isfile(os.path.join(support_dir, version_filename)):
with open(os.path.join(support_dir, version_filename)) as version_file:
version_from_file = version_file.read().split('\n')[0]

if version == version_from_file:
print('%s already exists, version is ok' % support_dir)
sys.exit(0)
else:
print('versions is not as expected -> replace with expected version')

cleanup()

# Make sure destination directory exists.
os.makedirs(support_dir, exist_ok=True)

# Download archive
arch_url = 'https://github.com/avast-tl/retdec-support/releases/download/%s/%s' % (version, arch_name)
print('Downloading archive from %s ...' % arch_url)

try:
urllib.request.urlretrieve(arch_url, arch_path)
except (urllib.request.HTTPError, urllib.request.URLError):
print('ERROR: download failed')
cleanup()
sys.exit(1)

# Compute hash of the downloaded archive.
print('Verfifying archive\'s checksum ...')

sha256 = hashlib.sha256()
with open(arch_path, 'rb') as f:
try:
sha256.update(f.read())
except IOError:
print('ERROR: failed to compute the SHA-256 hash of the archive')
cleanup()
sys.exit(1)

sha256hash = sha256.hexdigest()

# Check that hash is ok.
if sha256hash != sha256hash_ref:
print('ERROR: downloaded archive is invalid (SHA-256 hash check failed)')
cleanup()
sys.exit(1)

# Unpack archive.
print('Unpacking archive ...')
with tarfile.open(arch_path) as tar:
try:
tar.extractall(support_dir)
except tarfile.ExtractError:
print('ERROR: failed to unpack the archive')
cleanup()
sys.exit(1)

# Remove archive.
os.remove(arch_path)

print('RetDec support directory downloaded OK')
sys.exit(0)
12 changes: 12 additions & 0 deletions scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ endif()
install(PROGRAMS "retdec-signature-from-library-creator.sh" DESTINATION bin)
install(PROGRAMS "retdec-unpacker.sh" DESTINATION bin)
install(PROGRAMS "retdec-utils.sh" DESTINATION bin)

# copy python scripts
install(PROGRAMS "retdec_config.py" DESTINATION bin)
install(PROGRAMS "retdec_archive_decompiler.py" DESTINATION bin)
install(PROGRAMS "retdec_decompiler.py" DESTINATION bin)
install(PROGRAMS "retdec_fileinfo.py" DESTINATION bin)
if(RETDEC_TESTS)
install(PROGRAMS "retdec_tests_runner.py" DESTINATION bin)
endif()
install(PROGRAMS "retdec_signature_from_library_creator.py" DESTINATION bin)
install(PROGRAMS "retdec_unpacker.py" DESTINATION bin)
install(PROGRAMS "retdec_utils.py" DESTINATION bin)
Loading

0 comments on commit 4de4f49

Please sign in to comment.