Initial commit
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
.idea
|
||||||
|
/build
|
||||||
|
/include/*
|
||||||
|
/lib/*
|
||||||
|
|
||||||
|
# This part is taken from Github's macOS gitignore template
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
28
LICENSE
Normal file
28
LICENSE
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2024, nix-enthusiast
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# OBJDetect
|
||||||
|
|
||||||
|
OBJDetect is a program made in Go as an example of how to use [unildd](https://github.com/nix-enthusiast/unildd) library
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Python >= 3.10
|
||||||
|
- Cargo
|
||||||
|
- Go >= 1.17
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
- Clone this git repository:
|
||||||
|
|
||||||
|
```git clone https://github.com/nix-enthusiast/objdetect```
|
||||||
|
|
||||||
|
- Go into the repository:
|
||||||
|
|
||||||
|
```cd objdetect```
|
||||||
|
|
||||||
|
- Run the `build.py` file:
|
||||||
|
|
||||||
|
```
|
||||||
|
python3 build.py --build # To build the program
|
||||||
|
python3 build.py --run # To directly run the program
|
||||||
|
python3 build.py --clean # To remove the build directory
|
||||||
|
```
|
||||||
|
|
||||||
|
- Take the file named `objdetect` (or `objdetect.exe` in Windows) from the directory named `build` and put it anywhere you want!
|
||||||
|
|
||||||
|
## ⚠️ A Small Warning
|
||||||
|
|
||||||
|
Since it uses [unildd](https://github.com/nix-enthusiast/unildd) library, the library has to be accessible by the program. To do it on
|
||||||
|
|
||||||
|
### Windows:
|
||||||
|
|
||||||
|
You can put the library in any folder which is in the `%PATH` variable or put them in the same place
|
||||||
|
|
||||||
|
```
|
||||||
|
cp build\target\release\unildd.dll \the\folder\in\the\path\var
|
||||||
|
#or
|
||||||
|
cp build\target\release\unildd.dll \the\folder\which\includes\objdetect
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux and macOS:
|
||||||
|
The same thing as what we do in Windows but the variable is:
|
||||||
|
|
||||||
|
- `LD_LIBRARY_PATH` for Linux[^1]
|
||||||
|
- `DYLD_LIBRARY_PATH` for macOS[^2]
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
cp build/target/release/unildd.dll /the/folder/in/the/variable
|
||||||
|
#or
|
||||||
|
cp build/target/release/unildd.dll /the/folder/which/includes/objdetect
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other OSes
|
||||||
|
If your OS is not listed on here, please take a look at the documentation of your OS to find the path and do the same (or similar since OSes work different) thing as what we did above
|
||||||
|
|
||||||
|
## License
|
||||||
|
This library is licensed under [BSD-3 Clause License](https://choosealicense.com/licenses/bsd-3-clause/)
|
||||||
|
|
||||||
|
[^1]: https://man7.org/linux/man-pages/man8/ld.so.8.html#:~:text=LD_LIBRARY_PATH%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20A%20list%20of%20directories%20in%20which%20to%20search%20for%20ELF%20libraries%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20at%20execution%20time.
|
||||||
|
[^2]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/UsingDynamicLibraries.html#:~:text=You%20may%20also,DYLD_FALLBACK_LIBRARY_PATH
|
||||||
37
build.py
Normal file
37
build.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from os import system
|
||||||
|
from sys import argv, stderr
|
||||||
|
from platform import system as os_name
|
||||||
|
|
||||||
|
def build():
|
||||||
|
system("mkdir -p build")
|
||||||
|
system("git clone https://github.com/nix-enthusiast/unildd.git build/unildd")
|
||||||
|
system("cargo build --release --manifest-path=build/unildd/Cargo.toml")
|
||||||
|
system("mkdir lib")
|
||||||
|
system("mkdir include")
|
||||||
|
|
||||||
|
# I know this logic is dodgy
|
||||||
|
match os_name():
|
||||||
|
case "Windows":
|
||||||
|
system("cp build\\unildd\\target\\release\\libunildd.dll lib")
|
||||||
|
case "Darwin":
|
||||||
|
system("cp build/unildd/target/release/libunildd.dylib lib")
|
||||||
|
case _:
|
||||||
|
system("cp build/unildd/target/release/libunildd.so lib")
|
||||||
|
|
||||||
|
system("cp build/unildd/header/unildd.h include")
|
||||||
|
|
||||||
|
|
||||||
|
match argv[1]:
|
||||||
|
case "--build" | "-b":
|
||||||
|
build()
|
||||||
|
system("go build -o build/objdetect")
|
||||||
|
|
||||||
|
case "--run" | "-r":
|
||||||
|
build()
|
||||||
|
system("go run main.go " + ' '.join(argv[2:]))
|
||||||
|
|
||||||
|
case "--clean" | "-c":
|
||||||
|
system("rm -rf build")
|
||||||
|
|
||||||
|
case f:
|
||||||
|
print("Invalid flag '" + f + "'", file=stderr)
|
||||||
144
main.go
Normal file
144
main.go
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -I./include
|
||||||
|
#cgo LDFLAGS: -L./lib -lunildd
|
||||||
|
#include "unildd.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toGoString(cStr *C.char) string {
|
||||||
|
if cStr == nil {
|
||||||
|
return "Undefined"
|
||||||
|
} else {
|
||||||
|
return C.GoString(cStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
argv := os.Args[1:]
|
||||||
|
isMultiple := len(argv) > 1
|
||||||
|
|
||||||
|
for _, fileName := range argv {
|
||||||
|
CFileName := C.CString(fileName)
|
||||||
|
|
||||||
|
fileContent, err := os.ReadFile(fileName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
|
|
||||||
|
if isMultiple {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
os.Exit(-25)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer := (*C.uint8_t)(unsafe.Pointer(&fileContent[0]))
|
||||||
|
|
||||||
|
size := C.size_t(len(fileContent))
|
||||||
|
|
||||||
|
readObjects := C.read_obj(CFileName, buffer, size, false)
|
||||||
|
objectsLength := int(readObjects.length)
|
||||||
|
objectArray := unsafe.Slice(readObjects.vec, objectsLength)
|
||||||
|
|
||||||
|
for i := 0; i < objectsLength; i++ {
|
||||||
|
var objectResult C.ULDDObjResult = objectArray[i]
|
||||||
|
|
||||||
|
object := objectResult.obj
|
||||||
|
err := objectResult.error
|
||||||
|
|
||||||
|
errorCode := int64(err.code)
|
||||||
|
|
||||||
|
if errorCode != 0 {
|
||||||
|
_, _ = fmt.Fprintln(os.Stderr, C.GoString(err.explanation))
|
||||||
|
|
||||||
|
if isMultiple {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
if errorCode < 0 {
|
||||||
|
os.Exit(int(err.code))
|
||||||
|
} else {
|
||||||
|
os.Exit(-25)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("File name: " + C.GoString(object.file_name))
|
||||||
|
|
||||||
|
memberName := ""
|
||||||
|
|
||||||
|
memberNamesLength := int(object.member_name.length)
|
||||||
|
memberNames := unsafe.Slice(object.member_name.vec, memberNamesLength)
|
||||||
|
for j := 0; j < memberNamesLength; j++ {
|
||||||
|
member := memberNames[j]
|
||||||
|
memberName += C.GoString(member)
|
||||||
|
|
||||||
|
if j+1 != int(object.member_name.length) {
|
||||||
|
memberName += " -> "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Member of: " + memberName)
|
||||||
|
|
||||||
|
fmt.Println("Executable format: " + toGoString(object.executable_format))
|
||||||
|
|
||||||
|
is64 := ""
|
||||||
|
|
||||||
|
if object.is_64 {
|
||||||
|
is64 = "64-bit"
|
||||||
|
} else {
|
||||||
|
is64 = "32-bit"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Word size: " + is64)
|
||||||
|
|
||||||
|
fmt.Println("OS: " + toGoString(object.os_type))
|
||||||
|
|
||||||
|
fmt.Println("File type: " + toGoString(object.file_type))
|
||||||
|
|
||||||
|
isStripped := ""
|
||||||
|
|
||||||
|
if object.is_stripped {
|
||||||
|
isStripped = "Yes"
|
||||||
|
} else {
|
||||||
|
isStripped = "No"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Is stripped: " + isStripped)
|
||||||
|
|
||||||
|
fmt.Println("CPU type: " + toGoString(object.cpu_type))
|
||||||
|
|
||||||
|
fmt.Println("CPU subtype: " + toGoString(object.cpu_subtype))
|
||||||
|
|
||||||
|
fmt.Println("Linker: " + toGoString(object.interpreter))
|
||||||
|
|
||||||
|
fmt.Println("Libraries:")
|
||||||
|
librariesLength := int(object.libraries.length)
|
||||||
|
libraries := unsafe.Slice(object.libraries.vec, librariesLength)
|
||||||
|
for _, library := range libraries {
|
||||||
|
fmt.Println(" -" + toGoString(library))
|
||||||
|
}
|
||||||
|
|
||||||
|
if i+1 != int(readObjects.length) {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
C.free_obj(readObjects, false)
|
||||||
|
C.free(unsafe.Pointer(CFileName))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user