binarly-io / idalib

Idiomatic Rust bindings for the IDA SDK, enabling the development of standalone analysis tools using IDA v9.0’s idalib
70 stars 8 forks source link

Potential improvement to build on Windows #15

Open 0xdea opened 21 hours ago

0xdea commented 21 hours ago

Hi,

Based on your recent work, I have implemented this GitHub workflow to build rhabdomancer.

However, with the original build script the workflow worked only on Windows. Therefore, I modified build.rs as you did in idalib.

After this, it worked properly on Linux and macOS, but broke on Windows with linker errors such as the following:

error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\rustcV2HRBF\\symbols.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.0m33kkt46idom2fih6k1x1346.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.35w0p1k66zslnpw86vobq5cal.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.3ky48sby89chwqswyj4l1tofw.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.3pftqwlu43m594b2o542bth68.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.6vyfhqynkur7hadnk5y1wzhie.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.7ynkhypq78nqbzratlic20520.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.9d4aigtuhkryklxjamq9uepfi.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.a50cnczgq1cjdxo3kd27oe7ft.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.cjlvu6neofw2mook4onleig2n.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.czes8sgwyoefffagfsvess9lj.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.d8lls732ji6bphg2djj9bmps2.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.e5h5ofb6i0qxg8kk8vwbrwy8f.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.e97fqfgx6843j1ru0nvydqfzb.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.6n35fnijy9xffi3y9gqf870nl.rcgu.o" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\librhabdomancer-066483e81d97dd1b.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libregex-4ff4a1a6fda4ff36.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libregex_automata-fa2ca57276511981.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libaho_corasick-ec02934e5c47eb28.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libregex_syntax-3197216a41c998ce.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libidalib-573d97f828b1283f.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libidalib_sys-a3642b233379764d.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libanyhow-2f080a79a8784b5f.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libwindows_sys-727f490854b3ae6c.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libwindows_targets-a8d7d374b366c185.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libautocxx-a93418417c09abdd.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libmoveit-f10386216b768de2.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libcxx-81558e42a9a62206.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\liblink_cplusplus-a8d6eac72e1d1151.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libconfig-62d9ccac560e19a8.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libpathdiff-52f93023823b099e.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libjson5-ac4b42fd3d7615c6.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libpest-a87268c1016ebd41.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libucd_trie-30e097e22f59c1a3.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libthiserror-e55ca4b3a58be939.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libron-b370150a4d[91](https://github.com/0xdea/rhabdomancer/actions/runs/11821974262/job/32937952412#step:8:92)0020.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libbitflags-823ce45a7b34f745.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libbase64-63b8933f[92](https://github.com/0xdea/rhabdomancer/actions/runs/11821974262/job/32937952412#step:8:93)665097.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libserde_json-82abf62eaa41a5f6.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libitoa-04e24634090f2ce2.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libryu-d280ec8740639613.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libtoml-c37df6a87100e033.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libtoml_edit-a4daabcfeec28294.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libserde_spanned-06a9ca2d53440bc6.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libindexmap-a68ef6ac80384756.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libequivalent-f33e1acf4c0d5cb7.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libhashbrown-af0cf8d5cd4c1928.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libwinnow-6df87cbd89c4af39.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libtoml_datetime-99f776c923846127.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libnom-a7a0040bde9db9b4.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libmemchr-1470f7f8d21c0d84.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libini-52008add920ecba3.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libordered_multimap-9e724f791903eecd.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libdlv_list-42c97d0bcb2f0733.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libyaml_rust2-89f51ba4b94ccf53.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libencoding_rs-029fd47e34c6a175.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libarraydeque-e04f60e1cf372507.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libhashlink-f0a9589c92b8737e.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libhashbrown-78e96c5642b9cee2.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libahash-7142d224ec236be5.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libonce_cell-38cd374d1a342150.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libcfg_if-036dd9538a3083eb.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libzerocopy-d56e9c04db7cd48e.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\liballocator_api2-f0595b7c3a83e046.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libconvert_case-d8affc461c190067.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libunicode_segmentation-3b8e5af568da1120.rlib" "D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\libserde-a0c832addbf336e6.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-2df1f22abef96888.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-7fa781213a0698f8.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libwindows_targets-2440cb72ce7deb9b.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-f04b9120076f20fa.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-b521ee511095af2f.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-124aa6c4c6ef4b4c.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-c86a42f7194744c8.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-a416069596473508.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-e246a9218bd1ed0e.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-8f9b5fcbcd27c22e.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-65178e86c6c71ba8.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-fbeb171b69c59b37.rlib" "C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-e3a3e7896142045d.rlib" "windows.0.52.0.lib" "kernel32.lib" "kernel32.lib" "advapi32.lib" "ntdll.lib" "userenv.lib" "ws2_32.lib" "dbghelp.lib" "/defaultlib:msvcrt" "/NXCOMPAT" "/LIBPATH:D:\\a\\_temp/idasdk90\\lib\\x64_win_vc_64" "/LIBPATH:D:\\a\\_temp/idasdk90\\lib\\x64_win_vc_64" "/LIBPATH:C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.41.34120\\atlmfc\\lib\\x64" "/LIBPATH:D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\build\\cxx-16af93d4a4c175b1\\out" "/LIBPATH:C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.41.34120\\atlmfc\\lib\\x64" "/LIBPATH:D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\build\\link-cplusplus-6344401ff8122009\\out" "/LIBPATH:C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.41.34120\\atlmfc\\lib\\x64" "/LIBPATH:D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\build\\idalib-sys-bb8d1337379cdebd\\out" "/LIBPATH:C:\\Users\\runneradmin\\.cargo\\registry\\src\\index.crates.io-6f17d22bba15001f\\windows_x86_64_msvc-0.52.6\\lib" "/OUT:D:\\a\\rhabdomancer\\rhabdomancer\\target\\debug\\deps\\rhabdomancer.exe" "/OPT:REF,NOICF" "/DEBUG" "/PDBALTPATH:%_PDB%" "/NATVIS:C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/NATVIS:C:\\Users\\runneradmin\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis"
  = note: libidalib-573d97f828b1283f.rlib(idalib-573d97f828b1283f.idalib.1887c45eb1392a0d-cgu.2.rcgu.o) : error LNK2019: unresolved external symbol batch referenced in function _ZN6idalib16force_batch_mode17h7a78989e85c5193cE␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: int __cdecl func_t::compare(class func_t const &)const " (?compare@func_t@@QEBAHAEBV1@@Z) referenced in function "int __cdecl func_t_compare_autocxx_wrapper_0xe0bb547f53a54aa3(class func_t const &,class func_t const &)" (?func_t_compare_autocxx_wrapper_0xe0bb547f53a54aa3@@YAHAEBVfunc_t@@0@Z)␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "private: bool __cdecl gdl_graph_t::path(class node_set_t &,int,int)const " (?path@gdl_graph_t@@AEBA_NAEAVnode_set_t@@HH@Z) referenced in function "public: bool __cdecl gdl_graph_t::path_exists(int,int)const " (?path_exists@gdl_graph_t@@QEBA_NHH@Z)␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: void __cdecl gdl_graph_t::gen_gdl(struct _iobuf *)const " (?gen_gdl@gdl_graph_t@@QEBAXPEAU_iobuf@@@Z) referenced in function cxxbridge1$gdl_graph_t$gen_gdl␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: void __cdecl gdl_graph_t::gen_gdl(char const *)const " (?gen_gdl@gdl_graph_t@@QEBAXPEBD@Z) referenced in function cxxbridge1$gdl_graph_t$gen_gdl1␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: void __cdecl gdl_graph_t::gen_dot(struct _iobuf *)const " (?gen_dot@gdl_graph_t@@QEBAXPEAU_iobuf@@@Z) referenced in function cxxbridge1$gdl_graph_t$gen_dot␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: void __cdecl gdl_graph_t::gen_dot(char const *)const " (?gen_dot@gdl_graph_t@@QEBAXPEBD@Z) referenced in function cxxbridge1$gdl_graph_t$gen_dot1␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: int __cdecl segment_t::compare(class segment_t const &)const " (?compare@segment_t@@QEBAHAEBV1@@Z) referenced in function "int __cdecl segment_t_compare_autocxx_wrapper_0xe0bb547f53a54aa3(class segment_t const &,class segment_t const &)" (?segment_t_compare_autocxx_wrapper_0xe0bb547f53a54aa3@@YAHAEBVsegment_t@@0@Z)␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: void __cdecl carglist_t::print(class _qstring<char> *,struct cfunc_t const *)const " (?print@carglist_t@@QEBAXPEAV?$_qstring@D@@PEBUcfunc_t@@@Z) referenced in function "void __cdecl carglist_t_print_autocxx_wrapper_0xe0bb547f53a54aa3(struct carglist_t const &,class _qstring<char> *,struct cfunc_t const *)" (?carglist_t_print_autocxx_wrapper_0xe0bb547f53a54aa3@@YAXAEBUcarglist_t@@PEAV?$_qstring@D@@PEBUcfunc_t@@@Z)␍
          libidalib_sys-a3642b233379764d.rlib(7c3ccc32092e812f-gen0.o) : error LNK2019: unresolved external symbol "public: int __cdecl carglist_t::print(int,struct vc_printer_t &)const " (?print@carglist_t@@QEBAHHAEAUvc_printer_t@@@Z) referenced in function "int __cdecl carglist_t_print1_autocxx_wrapper_0xe0bb547f53a54aa3(struct carglist_t const &,int,struct vc_printer_t &)" (?carglist_t_print1_autocxx_wrapper_0xe0bb547f53a54aa3@@YAHAEBUcarglist_t@@HAEAUvc_printer_t@@@Z)␍
          D:\a\rhabdomancer\rhabdomancer\target\debug\deps\rhabdomancer.exe : fatal error LNK1120: 10 unresolved externals␍

error: could not compile `rhabdomancer` (bin "rhabdomancer") due to 1 previous error
Error: Process completed with exit code 1.

Eventually, I managed to make it work on all three platforms by applying this additional modification to build.rs, based on the workaround present in idalib-build.

Would it make sense to apply this workaround directly in configure_idasdk_linkage() instead of configure_linkage() in idalib-build? Also, how come idalib builds cleanly also on Windows without such a modification in build.rs? I'm definitely missing something here... Thanks!

xorpse commented 19 hours ago

Answering your second question first: I think the difference is that when we build just the idalib crate we're building a rlib, whereas when building rhabdomancer, we're building an executable. When building just the rlib we won't try to resolve the missing symbols, I think, but for an executable target, since the linker is invoked, and we're missing that directive, we will try to resolve all symbols, and for some reason they'll be missing from the .lib files we have with the SDK.. I've not dug further when making idalib work with Windows so I don't know if there's something I've missed that could fix this issue more fundamentally to give the same level of experience as Linux/macOS.

On your first question: I think it makes sense to just add the directive to configure_idasdk_linkage--it shouldn't break anything :).

Upd.: I've made the change to configure_idasdk_linkage--if all is fine, I'll make another release with that and your search API. I've also added some documentation about the workflows, hopefully it covers everything; any feedback/improvements would be welcome :).

0xdea commented 9 hours ago

It makes sense now, thanks for the clarification and for implementing the fix! The documentation about the workflows was needed, and it looks good. I'll try to finalize the search API today, so that you can make another release soon. Cheers!