done.so

what does this binary do

Dr.Binary

Call ghidra_open_server

Arguments
{"filepath": "/sandbox/done.so"}

Tool result
{"result":"compilerID: default\nimports[5]:\n  - functions[81]: __cxa_finalize,__cxa_atexit,__register_atfork,PyModuleDef_Init,PyThreadState_Get,PyInterpreterState_GetID,PyErr_SetString,PyObject_GetAttrString,PyModule_NewObject,_Py_Dealloc,PyModule_GetDict,PyImport_AddModule,PyObject_SetAttrString,PyOS_snprintf,PyErr_WarnEx,PyTuple_New,PyBytes_FromStringAndSize,PyUnicode_FromStringAndSize,PyObject_Hash,PyUnicode_Decode,PyUnicode_InternFromString,PyFloat_FromDouble,PyLong_FromLong,PyObject_SetAttr,PyImport_GetModuleDict,PyDict_GetItemString,PyDict_SetItemString,PySlice_New,PyDict_SetItem,_PyThreadState_UncheckedGet,PyObject_Vectorcall,PyCMethod_New,PyDict_New,PyErr_Occurred,__stack_chk_fail,PyObject_GetAttr,PyErr_ExceptionMatches,PyErr_Clear,PyImport_GetModule,PyObject_GenericGetAttr,_PyObject_GenericGetAttrWithDict,PyObject_IsTrue,PyException_GetTraceback,PyList_New,PyImport_ImportModuleLevelObject,PyModule_GetName,PyUnicode_FromString,PyUnicode_Concat,PyErr_Format,PyCode_NewEmpty,PyMem_Realloc,PyFrame_New,PyTraceBack_Here,PyMem_Malloc,PyErr_NormalizeException,PyException_SetTraceback,_PyDict_GetItem_KnownHash,PyType_IsSubtype,PyObject_VectorcallDict,Py_EnterRecursiveCall,Py_LeaveRecursiveCall,PyObject_Call,PyErr_GivenExceptionMatches,PyNumber_Add,PyObject_VectorcallMethod,PyObject_GetIter,PyArg_ValidateKeywordArguments,PyDict_GetItemWithError,PyDict_Next,memcmp,PyObject_RichCompareBool,PyObject_Size,PyLong_FromSsize_t,PyNumber_Multiply,PySequence_Contains,_PyDict_NewPresized,PyUnicode_Format,PyObject_GetItem,PyNumber_Remainder,PyErr_SetObject,PyTuple_Pack\n    name: \n  - functions[0]:\n    name: libpython3.11.so.1.0\n  - functions[0]:\n    name: libdl.so\n  - functions[0]:\n    name: libc.so\n  - functions[0]:\n    name: libm.so\nexports[4]{address,name}:\n  0007c000,__real_main\n  00101f8c,_FINI_1\n  00101fa4,_FINI_0\n  00101fec,PyInit_done\nformat: Executable and Linking Format (ELF)\nlanguageID: "AARCH64:LE:64:v8A"\nprocessor: AARCH64\nendianess: Little Endian\nsegments[26]{name,start,end}:\n  segment_1.1,"00100000","00100237"\n  .note.android.ident,"00100238",001002cf\n  .dynsym,001002d0,00100c8f\n  .gnu.version,00100c90,00100d5f\n  .gnu.version_r,00100d60,00100d7f\n  .gnu.hash,00100d80,00100da3\n  .dynstr,00100da4,0010154a\n  .rela.dyn,"00101550","00101923"\n  .rela.plt,"00101928","00101987"\n  .rodata,"00101988",00101eb4\n  .eh_frame_hdr,00101eb8,00101ef3\n  .eh_frame,00101ef8,00101f8b\n  .text,00101f8c,0011d6f3\n  .plt,0011d700,0011d75f\n  .data.rel.ro,"00121760",00121b17\n  .fini_array,00121b18,00121b27\n  .dynamic,00121b28,00121cb7\n  .got,00121cb8,00121fbf\n  .got.plt,00121fc0,00121ff7\n  .relro_padding,00121ff8,00121fff\n  .data,00125ff8,001260f7\n  .bss,001260f8,"00126937"\n  EXTERNAL,"00127000","00127327"\n  .comment,".comment::00000000",".comment::000000cb"\n  .shstrtab,".shstrtab::00000000",".shstrtab::000000e6"\n  _elfSectionHeaders,"_elfSectionHeaders::00000000","_elfSectionHeaders::000005ff"\naddressSize: 64 bit\nimageBase: "00100000"\nnamedFunctions[2]{address,name}:\n  00101f8c,_FINI_1\n  00101fec,PyInit_done\nstrings[101]{address,value}:\n  00101bf3,done.lolIOIOooollIlo\n  "00101082",__stack_chk_fail\n  001019b6,exactly\n  "00100e84",PyExc_RuntimeError\n  "00101066",PyErr_Occurred\n  001014cd,PyTuple_Pack\n  0010119e,PyUnicode_FromString\n  "00100e67",_Py_Dealloc\n  ".shstrtab::000000b1",.got.plt\n  "00101286",PyType_IsSubtype\n  "00100e02",PyInterpreterState_GetID\n  00100fff,PyDict_SetItem\n  00101d64,cline_in_traceback\n  "00101128",_Py_FalseStruct\n  00100fcf,PyDict_SetItemString\n  "00100e54",PyModule_NewObject\n  0010142c,PyLong_FromSsize_t\n  "00101161",PyList_New\n  00101e5c,stdout\n  0010100e,_PyThreadState_UncheckedGet\n  00101cf0,BLACK\n  0010136c,PyMethod_Type\n  00101d9e,headers\n  0010153a,libdl.so\n  00101c86,builtins\n  00100ec1,Py_Version\n  00100f92,PyObject_SetAttr\n  00101c27,Interpreter change detected - this module can only be loaded into one interpreter per process.\n  00100ee7,PyTuple_New\n  00101d2f,OoloollOIoo\n  001014ae,PyExc_KeyError\n  "00101465",_PyDict_NewPresized\n  00101a0b,%s() got multiple values for keyword argument '%U'\n  00101b76,done.loOIOlOIoll\n  00101f01,zR\n  00101dab,_initializing\n  ".shstrtab::00000039",.gnu.hash\n  00100e2d,PyErr_SetString\n  00101dd9,module\n  "00101479",PyUnicode_Format\n  00101e8d,loOIOlOIoll\n  "00101e47",sleep\n  00101b34,build_temp/done.pyx\n  0010149b,PyNumber_Remainder\n  00101d0d,IoIOIIIIOlOollOl\n  00100fa3,PyImport_GetModuleDict\n  0010102a,_Py_TrueStruct\n  00101e1d,pyfiglet\n  "00101e81",width\n  00101ea5,lolIOIOooollIlo\n  ".shstrtab::000000d4",.comment\n  0010105b,PyDict_New\n  00101c08,'%.200s' object is unsliceable\n  ".shstrtab::0000001d",.gnu.version\n  00100ecc,PyOS_snprintf\n  001010dc,PyImport_GetModule\n  00100ff3,PySlice_New\n  00100dc1,__register_atfork\n  ".shstrtab::0000005f",.rodata\n  00101a3e,does not match\n  0010137a,PyTuple_Type\n  00101a6f,loader\n  00101be1,at least\n  00101db9,input\n  ".shstrtab::00000067",.eh_frame_hdr\n  00101a76,package\n  001011c4,PyErr_Format\n  00100f54,PyUnicode_InternFromString\n  00100fe4,_Py_NoneStruct\n  00100ddf,PyModuleDef_Init\n  001011b3,PyUnicode_Concat\n  00101cfb,Figlet\n  001012fb,PyErr_GivenExceptionMatches\n  00101dfe,ollOolIoIIoO\n  00101d3f,RESET\n  00100f82,PyLong_FromLong\n  "00101405",PyObject_RichCompareBool\n  ".comment::000000b9","Linker: LLD 21.1.6"\n  00101adc,parent\n  00101cb2,%s() got an unexpected keyword argument '%U'\n  ".shstrtab::000000ba",.relro_padding\n  00101d85,decode\n  "00101219",PyErr_NormalizeException\n  00101e3e,requests\n  00101b6d,path\n  "001013e3",PyDict_Next\n  "001012e9",PyExc_SystemError\n  00100fba,PyDict_GetItemString\n  00101ac9,init done\n  "00100e97",PyImport_AddModule\n  00101d8c,encode\n  "00101352",PyObject_VectorcallMethod\n  00101ad3,file\n  "00101138",PyObject_IsTrue\n  00101d93,flush\n  "00101e33",renderText\n  "00101e99",oOlOoloIIlO\n  ".shstrtab::0000004b",.rela.dyn\n  "00101e17",print\n  "00101148",PyException_GetTraceback\n  truncated... (more than 100 strings found),truncated\nfileSize: 125104 bytes\nentryPoint: """}

Call ghidra_decompile_function

Arguments
{
  "filepath": "/sandbox/done.so",
  "name_or_address": "PyInit_done"
}
Tool result
{"result":"\nvoid PyInit_done(void)\n\n{\n  (*(code *)PTR_PyModuleDef_Init_00121cb8)(&DAT_00125ff8);\n  return;\n}\n\n"}

Call ghidra_decompile_function

Arguments
{"filepath": "/sandbox/done.so", "name_or_address": "__real_main"}

Tool result
{"result":"Function not found"}

Call ghidra_decompile_function

Arguments
{"filepath": "/sandbox/done.so", "name_or_address": "0x7c000"}

Tool result
{"result":"Function not found"}

Call ghidra_list_methods

Arguments
{"filepath": "/sandbox/done.so", "limit": 50}

Tool result
{"result":["_FINI_1 @ 00101f8c","FUN_00101f9c @ 00101f9c","_FINI_0 @ 00101fa4","FUN_00101fac @ 00101fac","FUN_00101fc0 @ 00101fc0","FUN_00101fdc @ 00101fdc","PyInit_done @ 00101fec","FUN_00102000 @ 00102000","FUN_00104b68 @ 00104b68","FUN_00104c40 @ 00104c40","FUN_00104e84 @ 00104e84","FUN_00104f04 @ 00104f04","FUN_00104ff8 @ 00104ff8","FUN_00105088 @ 00105088","FUN_00105214 @ 00105214","FUN_00105598 @ 00105598","FUN_001057a4 @ 001057a4","FUN_00105860 @ 00105860","FUN_001058e8 @ 001058e8","FUN_00105b3c @ 00105b3c","FUN_00105be0 @ 00105be0","FUN_00105d58 @ 00105d58","FUN_00105e1c @ 00105e1c","FUN_00105e6c @ 00105e6c","FUN_00105ed4 @ 00105ed4","FUN_00105f98 @ 00105f98","FUN_00106e38 @ 00106e38","FUN_00107004 @ 00107004","FUN_00107318 @ 00107318","FUN_001073b0 @ 001073b0","FUN_00108d4c @ 00108d4c","FUN_0011d500 @ 0011d500","FUN_0011d5dc @ 0011d5dc","FUN_0011d700 @ 0011d700","__cxa_finalize @ 0011d720","__cxa_atexit @ 0011d730","__register_atfork @ 0011d740","__stack_chk_fail @ 0011d750","__cxa_finalize @ 00127000","__cxa_atexit @ 00127008","__register_atfork @ 00127010","PyModuleDef_Init @ 00127018","PyThreadState_Get @ 00127020","PyInterpreterState_GetID @ 00127028","PyErr_SetString @ 00127038","PyObject_GetAttrString @ 00127040","PyModule_NewObject @ 00127048","Py_Dealloc @ 00127050","PyModule_GetDict @ 00127058","PyImport_AddModule @ 00127068"]}

Call ghidra_decompile_function

Arguments
{"filepath": "/sandbox/done.so", "name_or_address": "FUN_00102000"}

Tool result
{"result":"\nlong * FUN_00102000(undefined8 param_1)\n\n{\n  long lVar1;\n  int iVar2;\n  long lVar3;\n  long *plVar4;\n  long plVar5;\n  \n  lVar3 = ((code )PTR_PyThreadState_Get_00121cc0)();\n  lVar3 = ((code )PTR_PyInterpreterState_GetID_00121cc8)((undefined8 *)(lVar3 + 0x10));\n  plVar4 = DAT_00126120;\n  if (lVar3 != -1) {\n    lVar1 = lVar3;\n    if ((DAT_00126090 == -1) || (lVar1 = DAT_00126090, DAT_00126090 == lVar3)) {\n      DAT_00126090 = lVar1;\n      if (DAT_00126120 != (long *)0x0) {\n        *DAT_00126120 = *DAT_00126120 + 1;\n        return plVar4;\n      }\n      plVar4 = (long )((code *)PTR_PyObject_GetAttrString_00121ce0)(param_1,&DAT_00101bdc);\n      if (plVar4 != (long *)0x0) {\n        plVar5 = (long )((code *)PTR_PyModule_NewObject_00121ce8)();\n        lVar3 = *plVar4;\n        plVar4 = lVar3 + -1;\n        if (lVar3 + -1 == 0) {\n          ((code *)PTR__Py_Dealloc_00121cf0)(plVar4);\n        }\n        if (plVar5 == (long *)0x0) {\n          return (long )0x0;\n        }\n        lVar3 = ((code *)PTR_PyModule_GetDict_00121cf8)(plVar5);\n        if ((((lVar3 != 0) &&\n             (iVar2 = FUN_00104b68(param_1,lVar3,"loader","loader",1), -1 < iVar2)) &&\n            (iVar2 = FUN_00104b68(param_1,lVar3,"origin","file",1), -1 < iVar2)) &&\n           ((iVar2 = FUN_00104b68(param_1,lVar3,"parent","package",1), -1 < iVar2 &&\n            (iVar2 = FUN_00104b68(param_1,lVar3,"submodule_search_locations","path",0),\n            -1 < iVar2)))) {\n          return plVar5;\n        }\n        lVar3 = *plVar5;\n        plVar5 = lVar3 + -1;\n        if (lVar3 + -1 == 0) {\n          ((code )PTR__Py_Dealloc_00121cf0)(plVar5);\n        }\n      }\n    }\n    else {\n      ((code )PTR_PyErr_SetString_00121cd8)\n                ((undefined8 *)PTR_PyExc_ImportError_00121cd0,\n                 "Interpreter change detected - this module can only be loaded into one interpreter per process."\n                );\n    }\n  }\n  return (long )0x0;\n}\n\n"}

Call ghidra_list_strings

Arguments
{"filepath": "/sandbox/done.so", "filter": "oll"}

Tool result
{"result":["00101b76: "done.loOIOlOIoll"","00101bf3: "done.lolIOIOooollIlo"","00101d0d: "IoIOIIIIOlOollOl"","00101d1e: "OoOlOlIlOOOIlOll"","00101d2f: "OoloollOIoo"","00101dbf: "lIOllloOoooIOIOo"","00101dfe: "ollOolIoIIoO"","00101e8d: "loOIOlOIoll"","00101ea5: "lolIOIOooollIlo""]}

Call sandbox_execute

Arguments
{"command": "file /sandbox/done.so"}

Tool result
{"exitCode":0,"stdout":"/sandbox/done.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, for Android 24, built by NDK r28c (13676358), stripped\n","stderr":""}

Call ghidra_search_functions_by_name

Arguments
{"filepath": "/sandbox/done.so", "query": "IO"}

Tool result
{"result":["PyErr_ExceptionMatches @ 00127160","PyErr_GivenExceptionMatches @ 00127250","PyErr_NormalizeException @ 001271f8","PyException_GetTraceback @ 00127198","PyException_SetTraceback @ 00127200"]}

Call ghidra_get_xrefs_to

Arguments
{"filepath": "/sandbox/done.so", "address": "0x00101bf3"}

Tool result
{"result":["From 0010b08c [PARAM]"]}

Call ghidra_decompile_function

Arguments
{"filepath": "/sandbox/done.so", "name_or_address": "0x0010b08c"}

Tool result
{"result":"Function not found"}

Call ghidra_get_function

Arguments
{"filepath": "/sandbox/done.so", "name_or_address": "0x0010b08c"}

Tool result
{"result":"No function found at 0x0010b08c"}

Call ghidra_get_xrefs_to

Arguments
{"filepath": "/sandbox/done.so", "address": "0x00101d2f"}

Tool result
{"result":["From 001217d8 [DATA]"]}

Call sandbox_execute

Arguments
{"command": "python3 -c \"import sys; print(sys.version)\""}

Tool result
{"exitCode":0,"stdout":"3.13.9 (main, Oct 15 2025, 14:56:22) [GCC 15.2.0]\n","stderr":""}

Call ghidra_list_data_items

Arguments
{"filepath": "/sandbox/done.so", "limit": 50}

Tool result
{"result":["00100000: (unnamed) = ","00100040: Elf64_Phdr_ARRAY_00100040 = ","00100238: ElfNote_8_132_00100238 = ","001002d0: __DT_SYMTAB = ","00100c90: __DT_VERSYM = 0h","00100c92: (unnamed) = 2h","00100c94: (unnamed) = 2h","00100c96: (unnamed) = 2h","00100c98: (unnamed) = 1h","00100c9a: (unnamed) = 1h","00100c9c: (unnamed) = 1h","00100c9e: (unnamed) = 1h","00100ca0: (unnamed) = 1h","00100ca2: (unnamed) = 1h","00100ca4: (unnamed) = 1h","00100ca6: (unnamed) = 1h","00100ca8: (unnamed) = 1h","00100caa: (unnamed) = 1h","00100cac: (unnamed) = 1h","00100cae: (unnamed) = 1h","00100cb0: (unnamed) = 1h","00100cb2: (unnamed) = 1h","00100cb4: (unnamed) = 1h","00100cb6: (unnamed) = 1h","00100cb8: (unnamed) = 1h","00100cba: (unnamed) = 1h","00100cbc: (unnamed) = 1h","00100cbe: (unnamed) = 1h","00100cc0: (unnamed) = 1h","00100cc2: (unnamed) = 1h","00100cc4: (unnamed) = 1h","00100cc6: (unnamed) = 1h","00100cc8: (unnamed) = 1h","00100cca: (unnamed) = 1h","00100ccc: (unnamed) = 1h","00100cce: (unnamed) = 1h","00100cd0: (unnamed) = 1h","00100cd2: (unnamed) = 1h","00100cd4: (unnamed) = 1h","00100cd6: (unnamed) = 1h","00100cd8: (unnamed) = 1h","00100cda: (unnamed) = 1h","00100cdc: (unnamed) = 1h","00100cde: (unnamed) = 1h","00100ce0: (unnamed) = 1h","00100ce2: (unnamed) = 1h","00100ce4: (unnamed) = 2h","00100ce6: (unnamed) = 1h","00100ce8: (unnamed) = 1h","00100cea: (unnamed) = 1h"]}

Call ghidra_get_data_by_address

Arguments
{"filepath": "/sandbox/done.so", "address": "0x001217d8"}

Tool result
{"result":"00101d2f"}

This is a Python 3.11 extension module for Android (ARM64). Key observations:

  • Python module named "done" with submodules like done.loOIOlOIoll and done.lolIOIOooollIlo
  • Obfuscated module/function names using character patterns (OoloollOIoo, IoIOIIIIOlOollOl, etc.)
  • Uses pyfiglet (ASCII art text rendering) and requests library
  • Initialization checks: Validates it's loaded into single Python interpreter per process
  • Potential functionality: Likely prints ASCII art banners, makes HTTP requests, handles input/decode/encode operations
  • Built for Android 24+ using NDK r28c, but depends on Python 3.11

The obfuscated naming and combination of pyfiglet + requests suggests this may be malware or a CTF challenge binary that displays messages and communicates with external servers.