From 170a204e34cbc97dd0124ae166a4d529852220d8 Mon Sep 17 00:00:00 2001 From: yuannan Date: Wed, 14 Jan 2026 23:03:12 +0000 Subject: [PATCH] pince: init at 0.4.5 --- pkgs/by-name/pi/pince/libptrscan/Cargo.lock | 25 +++ pkgs/by-name/pi/pince/package.nix | 186 ++++++++++++++++++++ pkgs/by-name/pi/pince/set-gdb-path.patch | 108 ++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 pkgs/by-name/pi/pince/libptrscan/Cargo.lock create mode 100644 pkgs/by-name/pi/pince/package.nix create mode 100644 pkgs/by-name/pi/pince/set-gdb-path.patch diff --git a/pkgs/by-name/pi/pince/libptrscan/Cargo.lock b/pkgs/by-name/pi/pince/libptrscan/Cargo.lock new file mode 100644 index 000000000000..0b44473dd19f --- /dev/null +++ b/pkgs/by-name/pi/pince/libptrscan/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "machx" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac9b6ef56836bbcf4a55a3b7ac0964fdeb988ee4ef288a34b184d156965bd93" +dependencies = [ + "libc", +] + +[[package]] +name = "libptrscan" +version = "0.7.4" +dependencies = [ + "machx", +] diff --git a/pkgs/by-name/pi/pince/package.nix b/pkgs/by-name/pi/pince/package.nix new file mode 100644 index 000000000000..44e0a0e2a7dd --- /dev/null +++ b/pkgs/by-name/pi/pince/package.nix @@ -0,0 +1,186 @@ +{ + stdenv, + lib, + fetchFromGitHub, + replaceVars, + nix-update-script, + + rustPlatform, + + cmake, + makeWrapper, + + python3Packages, + python3, + gdb, + qt6, + gtk3, + gobject-introspection, +}: + +let + libptrscan = rustPlatform.buildRustPackage { + pname = "libptrscan"; + version = "0.7.4-unstable-2024-09-13"; + + src = fetchFromGitHub { + owner = "kekeimiku"; + repo = "PointerSearcher-X"; + rev = "ba2b5eab4856aa4ffb3ece0bd2c7d0917fa4e6ce"; # last commit on pince_fix_32 branch + hash = "sha256-skOM2dx+u7dYbWywaC8dtUuJuXzc4Mm6skBbMfaTwfY="; + }; + + cargoLock.lockFile = ./libptrscan/Cargo.lock; + + postPatch = '' + cp ${./libptrscan/Cargo.lock} Cargo.lock + chmod +w Cargo.lock + ''; + + cargoBuildFlags = [ "-p libptrscan" ]; + + postInstall = '' + install -Dm644 libptrscan/ptrscan.py -t "$out"/lib/ + ''; + }; + + pythonEnv = python3.withPackages ( + ps: with ps; [ + capstone + keyboard + keystone-engine + pexpect + pygdbmi + pygobject3 + pyqt6 + ] + ); + + gdb' = gdb.override { + python3 = pythonEnv; + }; + + # LD_LIBRARY_PATH libraries + LDPath = lib.makeLibraryPath [ + (lib.getLib stdenv.cc.cc) + gtk3 + gdb' + ]; + + # GI_TYPELIB_PATH libraries + GIPath = lib.makeSearchPath "lib/girepository-1.0" [ + gtk3 + gobject-introspection + ]; +in + +python3Packages.buildPythonApplication rec { + pname = "pince"; + version = "0.4.5"; + pyproject = false; + + src = fetchFromGitHub { + owner = "korcankaraokcu"; + repo = "PINCE"; + tag = "v${version}"; + hash = "sha256-NgoZmmcMEPGpIF3IPEIoeRPOwwuxdinBlkeP0P5eVmU="; + fetchSubmodules = true; + }; + + patches = [ + (replaceVars ./set-gdb-path.patch { + gdb_exe_path = lib.getExe gdb'; + }) + ]; + + build-system = with python3Packages; [ + setuptools + ]; + + nativeBuildInputs = [ + cmake + gobject-introspection + qt6.qttools + qt6.wrapQtAppsHook + makeWrapper + ]; + + buildInputs = [ + pythonEnv + gdb' + gobject-introspection + qt6.qtbase + qt6.qtwayland + gtk3 + ]; + + dontUseCmakeConfigure = true; + + buildPhase = '' + runHook preBuild + + # libscanmem + pushd libscanmem-PINCE + + cmake -DCMAKE_BUILD_TYPE=Release . + make -j$NIX_BUILD_CORES + + install -Dm555 libscanmem.so -t ../libpince/libscanmem/ + install -Dm444 wrappers/scanmem.py -t ../libpince/libscanmem/ + popd + + # libptrscan + install -Dm555 ${libptrscan}/lib/libptrscan.so -t libpince/libptrscan + install -Dm444 ${libptrscan}/lib/ptrscan.py -t libpince/libptrscan + + # Translations + lrelease i18n/ts/* + mkdir -p i18n/qm + mv i18n/ts/*.qm i18n/qm/ + + runHook postBuild + ''; + + makeWrapperArgs = [ + ''--chdir "$out/lib/pince"'' + ''--prefix LD_LIBRARY_PATH : "${LDPath}"'' + ''--prefix GI_TYPELIB_PATH : "${GIPath}"'' + ''--set PYTHONPATH "$out/lib/pince"'' + ''--set PYTHONDONTWRITEBYTECODE "1"'' + ''--add-flags "$out/lib/pince/PINCE.py"'' + ''--prefix PATH : "${lib.makeBinPath [ pythonEnv ]}"'' + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/lib/pince/ + cp -r GUI i18n libpince media tr AUTHORS COPYING COPYING.CC-BY PINCE.py THANKS $out/lib/pince/ + + mkdir -p $out/bin + ln -s $out/lib/pince/PINCE.py $out/bin/pince + + runHook postInstall + ''; + + postFixup = '' + wrapPythonProgramsIn "$out/lib/pince" "$out $pythonPath" + ''; + + passthru = { + inherit libptrscan; + updateScript = nix-update-script { }; + }; + + meta = { + description = "Reverse engineering tool for games (Linux alternative to Cheat Engine)"; + homepage = "https://github.com/korcankaraokcu/PINCE"; + mainProgram = "pince"; + license = with lib.licenses; [ + gpl3Plus + cc-by-30 + ]; + platforms = lib.platforms.linux; + maintainers = with lib.maintainers; [ yuannan ]; + }; +} diff --git a/pkgs/by-name/pi/pince/set-gdb-path.patch b/pkgs/by-name/pi/pince/set-gdb-path.patch new file mode 100644 index 000000000000..d382f3e1c070 --- /dev/null +++ b/pkgs/by-name/pi/pince/set-gdb-path.patch @@ -0,0 +1,108 @@ +diff --git a/GUI/Settings/settings.py b/GUI/Settings/settings.py +index 05cf0fa..598ac87 100644 +--- a/GUI/Settings/settings.py ++++ b/GUI/Settings/settings.py +@@ -118,7 +118,7 @@ def set_default_settings(): + settings.setValue("bytes_per_scroll", 0x40) + settings.endGroup() + settings.beginGroup("Debug") +- settings.setValue("gdb_path", typedefs.PATHS.GDB) ++ settings.setValue("gdb_path", utils.get_default_gdb_path()) + settings.setValue("gdb_logging", False) + settings.setValue("interrupt_signal", "SIGINT") + settings.setValue("handle_signals", json.dumps(default_signals)) +diff --git a/GUI/Widgets/Settings/Settings.py b/GUI/Widgets/Settings/Settings.py +index 11ae44e..8ca87a1 100644 +--- a/GUI/Widgets/Settings/Settings.py ++++ b/GUI/Widgets/Settings/Settings.py +@@ -91,7 +91,7 @@ class SettingsDialog(QDialog, Ui_Dialog): + self.settings.setValue("MemoryView/show_memory_view_on_stop", self.checkBox_ShowMemoryViewOnStop.isChecked()) + self.settings.setValue("MemoryView/instructions_per_scroll", self.spinBox_InstructionsPerScroll.value()) + self.settings.setValue("MemoryView/bytes_per_scroll", self.spinBox_BytesPerScroll.value()) +- if not os.environ.get("APPDIR"): ++ if False: + selected_gdb_path = self.lineEdit_GDBPath.text() + if selected_gdb_path != states.gdb_path: + if utilwidgets.InputDialog(self, tr.GDB_RESET).exec(): +@@ -147,7 +147,7 @@ class SettingsDialog(QDialog, Ui_Dialog): + self.spinBox_InstructionsPerScroll.setValue(self.settings.value("MemoryView/instructions_per_scroll", type=int)) + self.spinBox_BytesPerScroll.setValue(self.settings.value("MemoryView/bytes_per_scroll", type=int)) + self.lineEdit_GDBPath.setText(str(self.settings.value("Debug/gdb_path", type=str))) +- if os.environ.get("APPDIR"): ++ if True: + self.label_GDBPath.setDisabled(True) + self.label_GDBPath.setToolTip(tr.UNUSED_APPIMAGE_SETTING) + self.lineEdit_GDBPath.setDisabled(True) +diff --git a/PINCE.py b/PINCE.py +index aa5da2f..b356458 100644 +--- a/PINCE.py ++++ b/PINCE.py +@@ -334,7 +334,7 @@ class MainForm(QMainWindow, MainWindow): + + settings.init_settings() + self.settings_changed() +- if os.environ.get("APPDIR"): ++ if True: + gdb_path = utils.get_default_gdb_path() + else: + gdb_path = states.gdb_path +@@ -1426,7 +1426,7 @@ class MainForm(QMainWindow, MainWindow): + + # Returns: a bool value indicates whether the operation succeeded. + def attach_to_pid(self, pid: int): +- attach_result = debugcore.attach(pid, states.gdb_path) ++ attach_result = debugcore.attach(pid, utils.get_default_gdb_path()) + if attach_result == typedefs.ATTACH_RESULT.SUCCESSFUL: + settings.apply_after_init() + scanmem.pid(pid) +@@ -1524,7 +1524,7 @@ class MainForm(QMainWindow, MainWindow): + self.flashAttachButtonTimer.start(100) + self.label_SelectedProcess.setText(tr.NO_PROCESS_SELECTED) + self.memory_view_window.setWindowTitle(tr.NO_PROCESS_SELECTED) +- if os.environ.get("APPDIR"): ++ if True: + gdb_path = utils.get_default_gdb_path() + else: + gdb_path = states.gdb_path +diff --git a/libpince/debugcore.py b/libpince/debugcore.py +index 987762f..9779120 100644 +--- a/libpince/debugcore.py ++++ b/libpince/debugcore.py +@@ -498,7 +498,7 @@ def init_gdb(gdb_path=utils.get_default_gdb_path()): + status_thread.start() + gdb_initialized = True + set_logging(False) +- if not is_appimage: ++ if False: + send_command("source ./gdbinit_venv") + set_pince_paths() + send_command("source " + utils.get_user_path(typedefs.USER_PATHS.GDBINIT)) +diff --git a/libpince/utils.py b/libpince/utils.py +index 604aeb3..0569a7e 100644 +--- a/libpince/utils.py ++++ b/libpince/utils.py +@@ -881,10 +881,7 @@ def get_user_path(user_path): + + + def get_default_gdb_path(): +- appdir = os.environ.get("APPDIR") +- if appdir: +- return appdir + "/usr/bin/gdb" +- return typedefs.PATHS.GDB ++ return "@gdb_exe_path@" + + + def execute_script(file_path): +diff --git a/tr/tr.py b/tr/tr.py +index 81e156c..74aef4c 100644 +--- a/tr/tr.py ++++ b/tr/tr.py +@@ -148,7 +148,7 @@ class TranslationConstants(QObject): + r"\[asdf\] --> search for opcodes that contain [asdf]" + ) + SEPARATE_PROCESSES_WITH = QT_TR_NOOP("Separate processes with {}") +- UNUSED_APPIMAGE_SETTING = QT_TR_NOOP("This setting is unused in AppImage builds") ++ UNUSED_APPIMAGE_SETTING = QT_TR_NOOP("This setting is unused in nixpkgs-based builds") + SELECT_GDB_BINARY = QT_TR_NOOP("Select the gdb binary") + QUIT_SESSION_CRASH = QT_TR_NOOP("Quitting current session will crash PINCE") + CONT_SESSION_CRASH = QT_TR_NOOP("Use global hotkeys or the commands 'interrupt' and 'c&' to stop/run the inferior")