mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-10-12 02:09:28 +00:00
Moved the new tool to tools/kgh and renamed it legic_kgh_tool. Added some validation so we don't return random bytes from non-kgh cards. Applied some styling to the new code. Added GPL header to new source file. Cleaned up the static build.
This commit is contained in:
@@ -523,26 +523,17 @@ endif(NOT SKIPREADLINE EQUAL 1)
|
||||
|
||||
if (BZIP2_FOUND)
|
||||
set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||
if (MINGW)
|
||||
set(BZIP2_LIBRARIES /mingw64/lib/libbz2.a)
|
||||
endif()
|
||||
set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK})
|
||||
endif (BZIP2_FOUND)
|
||||
|
||||
if (LZ4_FOUND)
|
||||
set(ADDITIONAL_DIRS ${LZ4_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||
if (MINGW)
|
||||
set(LZ4_LIBRARIES /mingw64/lib/liblz4.a)
|
||||
endif()
|
||||
set(ADDITIONAL_LNK ${LZ4_LIBRARIES} ${ADDITIONAL_LNK})
|
||||
endif (LZ4_FOUND)
|
||||
|
||||
if (ZLIB_FOUND)
|
||||
add_definitions("-DHAVE_ZLIB")
|
||||
set(ADDITIONAL_DIRS ${ZLIB_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||
if (MINGW)
|
||||
set(ZLIB_LIBRARIES /mingw64/lib/libz.a)
|
||||
endif()
|
||||
set(ADDITIONAL_LNK ${ZLIB_LIBRARIES} ${ADDITIONAL_LNK})
|
||||
endif (ZLIB_FOUND)
|
||||
|
||||
@@ -715,25 +706,19 @@ add_library(pm3rrg_rdv4_static STATIC
|
||||
${ADDITIONAL_SRC}
|
||||
)
|
||||
|
||||
add_executable(kgh_tools
|
||||
${PM3_ROOT}/client/experimental_lib/example_c/legic_migrate_tool.c
|
||||
)
|
||||
|
||||
set_target_properties(kgh_tools PROPERTIES OUTPUT_NAME "kgh_tools")
|
||||
if (MINGW)
|
||||
target_link_options(kgh_tools PRIVATE -static -static-libgcc)
|
||||
endif()
|
||||
|
||||
target_link_libraries(kgh_tools PRIVATE pm3rrg_rdv4_static)
|
||||
target_include_directories(kgh_tools PRIVATE
|
||||
${PM3_ROOT}/common
|
||||
${PM3_ROOT}/client/include
|
||||
${PM3_ROOT}/client/src
|
||||
${PM3_ROOT}/include
|
||||
)
|
||||
|
||||
target_compile_definitions(pm3rrg_rdv4 PRIVATE LIBPM3)
|
||||
target_compile_definitions(pm3rrg_rdv4_static PRIVATE LIBPM3)
|
||||
set(PM3_LIBRARY_TARGETS pm3rrg_rdv4 pm3rrg_rdv4_static)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
target_compile_definitions(${target} PRIVATE LIBPM3)
|
||||
target_compile_options(${target} PUBLIC -Wall -Werror -O3)
|
||||
target_include_directories(${target} PRIVATE
|
||||
${PM3_ROOT}/common
|
||||
${PM3_ROOT}/common_fpga
|
||||
${PM3_ROOT}/include
|
||||
${PM3_ROOT}/client/src
|
||||
${PM3_ROOT}/client/include
|
||||
${ADDITIONAL_DIRS}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
# Fail the build if a client source file is missing from TARGET_SOURCES.
|
||||
@@ -741,18 +726,22 @@ if (UNIX AND NOT APPLE)
|
||||
set_property(TARGET pm3rrg_rdv4 APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--no-undefined")
|
||||
endif()
|
||||
|
||||
target_compile_options(pm3rrg_rdv4 PUBLIC -Wall -Werror -O3)
|
||||
target_compile_options(pm3rrg_rdv4_static PUBLIC -Wall -Werror -O3)
|
||||
if (EMBED_READLINE)
|
||||
if (NOT SKIPREADLINE EQUAL 1)
|
||||
add_dependencies(pm3rrg_rdv4 ncurses readline)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
add_dependencies(${target} ncurses readline)
|
||||
endforeach()
|
||||
endif (NOT SKIPREADLINE EQUAL 1)
|
||||
endif (EMBED_READLINE)
|
||||
if (EMBED_BZIP2)
|
||||
add_dependencies(pm3rrg_rdv4 bzip2)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
add_dependencies(${target} bzip2)
|
||||
endforeach()
|
||||
endif (EMBED_BZIP2)
|
||||
if (EMBED_LZ4)
|
||||
add_dependencies(pm3rrg_rdv4 lz4)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
add_dependencies(${target} lz4)
|
||||
endforeach()
|
||||
endif (EMBED_LZ4)
|
||||
|
||||
if (MINGW)
|
||||
@@ -760,7 +749,9 @@ if (MINGW)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
# FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32
|
||||
# but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html
|
||||
target_compile_definitions(pm3rrg_rdv4 PRIVATE _ISOC99_SOURCE)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
target_compile_definitions(${target} PRIVATE _ISOC99_SOURCE)
|
||||
endforeach()
|
||||
|
||||
set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}")
|
||||
@@ -769,24 +760,6 @@ if (MINGW)
|
||||
set(ADDITIONAL_LNK ws2_32 ${ADDITIONAL_LNK})
|
||||
endif (MINGW)
|
||||
|
||||
target_include_directories(pm3rrg_rdv4 PRIVATE
|
||||
${PM3_ROOT}/common
|
||||
${PM3_ROOT}/common_fpga
|
||||
${PM3_ROOT}/include
|
||||
${PM3_ROOT}/client/src
|
||||
${PM3_ROOT}/client/include
|
||||
${ADDITIONAL_DIRS}
|
||||
)
|
||||
|
||||
target_include_directories(pm3rrg_rdv4_static PRIVATE
|
||||
${PM3_ROOT}/common
|
||||
${PM3_ROOT}/common_fpga
|
||||
${PM3_ROOT}/include
|
||||
${PM3_ROOT}/client/src
|
||||
${PM3_ROOT}/client/include
|
||||
${ADDITIONAL_DIRS}
|
||||
)
|
||||
|
||||
if (NOT APPLE)
|
||||
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
||||
@@ -810,37 +783,26 @@ if (NOT WHEREAMI_FOUND)
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK})
|
||||
endif (NOT WHEREAMI_FOUND)
|
||||
|
||||
target_link_libraries(pm3rrg_rdv4 PRIVATE
|
||||
m
|
||||
pm3rrg_rdv4_mbedtls
|
||||
pm3rrg_rdv4_cliparser
|
||||
pm3rrg_rdv4_lua
|
||||
pm3rrg_rdv4_tinycbor
|
||||
pm3rrg_rdv4_amiibo
|
||||
pm3rrg_rdv4_reveng
|
||||
pm3rrg_rdv4_hardnested
|
||||
pm3rrg_rdv4_id48
|
||||
pm3rrg_rdv4_mqtt
|
||||
pm3rrg_rdv4_vec
|
||||
${ADDITIONAL_LNK})
|
||||
|
||||
target_link_libraries(pm3rrg_rdv4_static PRIVATE
|
||||
m
|
||||
pm3rrg_rdv4_mbedtls
|
||||
pm3rrg_rdv4_cliparser
|
||||
pm3rrg_rdv4_lua
|
||||
pm3rrg_rdv4_tinycbor
|
||||
pm3rrg_rdv4_amiibo
|
||||
pm3rrg_rdv4_reveng
|
||||
pm3rrg_rdv4_hardnested
|
||||
pm3rrg_rdv4_id48
|
||||
pm3rrg_rdv4_mqtt
|
||||
pm3rrg_rdv4_vec
|
||||
${ADDITIONAL_LNK})
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
target_link_libraries(${target} PRIVATE
|
||||
m
|
||||
pm3rrg_rdv4_mbedtls
|
||||
pm3rrg_rdv4_cliparser
|
||||
pm3rrg_rdv4_lua
|
||||
pm3rrg_rdv4_tinycbor
|
||||
pm3rrg_rdv4_amiibo
|
||||
pm3rrg_rdv4_reveng
|
||||
pm3rrg_rdv4_hardnested
|
||||
pm3rrg_rdv4_id48
|
||||
pm3rrg_rdv4_mqtt
|
||||
pm3rrg_rdv4_vec
|
||||
${ADDITIONAL_LNK})
|
||||
endforeach()
|
||||
|
||||
if (NOT SKIPPTHREAD EQUAL 1)
|
||||
target_link_libraries(pm3rrg_rdv4 PRIVATE pthread)
|
||||
target_link_libraries(pm3rrg_rdv4_static PRIVATE pthread)
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
target_link_libraries(${target} PRIVATE pthread)
|
||||
endforeach()
|
||||
endif (NOT SKIPPTHREAD EQUAL 1)
|
||||
|
||||
if (NOT SKIPPYTHON EQUAL 1)
|
||||
@@ -852,4 +814,6 @@ if (NOT SKIPPYTHON EQUAL 1)
|
||||
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||
endif (NOT SKIPPYTHON EQUAL 1)
|
||||
|
||||
target_link_directories(pm3rrg_rdv4 PRIVATE ${ADDITIONAL_LNKDIRS})
|
||||
foreach (target IN LISTS PM3_LIBRARY_TARGETS)
|
||||
target_link_directories(${target} PRIVATE ${ADDITIONAL_LNKDIRS})
|
||||
endforeach()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See LICENSE.txt for the text of the license.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(legic_kgh_tool)
|
||||
|
||||
set(PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
||||
|
||||
add_subdirectory(${PM3_ROOT}/client/experimental_lib ${CMAKE_BINARY_DIR}/experimental_lib)
|
||||
|
||||
add_executable(legic_kgh_tool legic_kgh_tool.c)
|
||||
target_link_libraries(legic_kgh_tool PRIVATE pm3rrg_rdv4_static)
|
||||
target_include_directories(legic_kgh_tool PRIVATE
|
||||
${PM3_ROOT}/common
|
||||
${PM3_ROOT}/client/include
|
||||
${PM3_ROOT}/client/src
|
||||
${PM3_ROOT}/include
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
target_link_options(legic_kgh_tool PRIVATE -static -static-libgcc)
|
||||
endif()
|
||||
@@ -1,17 +1,18 @@
|
||||
# kgh_tools
|
||||
# legic_kgh_tool
|
||||
|
||||
## Running
|
||||
|
||||
`kgh_tools` is a small CLI wrapper around the LEGIC migration helpers.
|
||||
`legic_kgh_tool` reads KGH LEGIC card information, badge numbers, and stamps,
|
||||
and writes the supported KGH card layout.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
./kgh_tools COM13 read_badge_number
|
||||
./kgh_tools COM13 read_info
|
||||
./kgh_tools COM13 read_stamp
|
||||
./kgh_tools COM13 read_stamp -o stamp.bin
|
||||
./kgh_tools COM13 write_card 600001 --stamp-file stamp.bin
|
||||
./legic_kgh_tool COM13 read_badge_number
|
||||
./legic_kgh_tool COM13 read_info
|
||||
./legic_kgh_tool COM13 read_stamp
|
||||
./legic_kgh_tool COM13 read_stamp -o stamp.bin
|
||||
./legic_kgh_tool COM13 write_card 600001 --stamp-file stamp.bin
|
||||
```
|
||||
|
||||
Commands:
|
||||
@@ -19,15 +20,14 @@ Commands:
|
||||
- `read_badge_number` prints the badge number only.
|
||||
- `read_info` prints one-line JSON.
|
||||
- `read_stamp` prints the stamp as 8 hex chars, or writes raw 4 bytes with `-o/--output-file`.
|
||||
- `write_card <badge> (--stamp-file <path> | --stamp-hex <8hex>)` writes the card.
|
||||
- `write_card <badge> (--stamp-file <path> | --stamp-hex <8hex>)` writes the supported KGH layout.
|
||||
|
||||
Notes:
|
||||
|
||||
- Windows ProxSpace examples use `COM13`.
|
||||
- The stamp is 4 bytes and specific to your site.
|
||||
It can be specified as a .bin (use .e.g hexedit to create it)
|
||||
Or as a command-line option (less secure) as --stamp-hex (e.g.) 003EF417
|
||||
You can find the stamp on any card in use at your site by using read_info (see above)
|
||||
It can be specified as a `.bin` file or as `--stamp-hex` (for example, `003EF417`).
|
||||
- You can retrieve the stamp from a supported KGH card with `read_info` or `read_stamp`.
|
||||
- Linux examples usually use `/dev/ttyACM0` or similar.
|
||||
- `--verbose` can be useful for `read_badge_number` and `write_card`, if they fail for mysterious reasons.
|
||||
|
||||
@@ -36,42 +36,36 @@ Notes:
|
||||
Do this in ProxSpace:
|
||||
|
||||
```bash
|
||||
cd ~/proxmark3/client/experimental_lib
|
||||
cd ~/proxmark3/tools/kgh
|
||||
rm -rf build-lite
|
||||
cmake -G "MSYS Makefiles" -S . -B build-lite \
|
||||
-DSKIPPYTHON=1 \
|
||||
-DSKIPREADLINE=1 \
|
||||
-DSKIPJANSSYSTEM=1 \
|
||||
-DSKIPJANSSONSYSTEM=1 \
|
||||
-DSKIPWHEREAMISYSTEM=1 \
|
||||
-DSKIPBT=1
|
||||
cmake --build build-lite --target kgh_tools -j
|
||||
objdump -p build-lite/kgh_tools.exe | grep -i "DLL Name"
|
||||
cmake --build build-lite --target legic_kgh_tool -j
|
||||
objdump -p build-lite/legic_kgh_tool.exe | grep -i "DLL Name"
|
||||
```
|
||||
|
||||
## Building Linux
|
||||
|
||||
```bash
|
||||
cd client/experimental_lib
|
||||
cd tools/kgh
|
||||
rm -rf build-linux
|
||||
cmake -S . -B build-linux \
|
||||
-DSKIPPYTHON=1 \
|
||||
-DSKIPREADLINE=1 \
|
||||
-DSKIPJANSSYSTEM=1 \
|
||||
-DSKIPJANSSONSYSTEM=1 \
|
||||
-DSKIPWHEREAMISYSTEM=1 \
|
||||
-DSKIPBT=1
|
||||
cmake --build build-linux --target kgh_tools -j
|
||||
ldd build-linux/kgh_tools
|
||||
cmake --build build-linux --target legic_kgh_tool -j
|
||||
ldd build-linux/legic_kgh_tool
|
||||
```
|
||||
|
||||
## Static Link Notes
|
||||
|
||||
- `kgh_tools` is linked against `pm3rrg_rdv4_static`.
|
||||
- `legic_kgh_tool` is linked against `pm3rrg_rdv4_static`.
|
||||
- On MinGW, CMake adds `-static -static-libgcc` for the target.
|
||||
- Linux builds are not the same as the ProxSpace single-EXE deployment.
|
||||
- If CMakeCache paths change between ProxSpace and a native shell, delete the build dir and reconfigure.
|
||||
|
||||
## Existing Helper Scripts
|
||||
|
||||
- `01make_lib.sh` creates `build/`, runs `cmake ..`, then `make -j`.
|
||||
- `01make_lib_continue.sh` reruns `make -j` in `build/`.
|
||||
- `00make_swig.sh` regenerates the SWIG wrappers before building the library.
|
||||
+34
-4
@@ -1,3 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -238,6 +254,14 @@ static void free_legic_read_result(legic_read_result_t *res) {
|
||||
memset(&res->card, 0, sizeof(res->card));
|
||||
}
|
||||
|
||||
static bool is_kgh_card(const uint8_t *dump, uint16_t len) {
|
||||
return len >= sizeof(k_legic_template_head) &&
|
||||
dump[5] == 0x60 && dump[6] == 0xEA &&
|
||||
dump[7] == 0x9F && dump[8] == 0xFF &&
|
||||
dump[22] == 0x0D && dump[23] == 0xC0 &&
|
||||
dump[24] == 0x08 && dump[25] == 0x00;
|
||||
}
|
||||
|
||||
static const char *classify_legic_card(const uint8_t *dump, uint16_t len) {
|
||||
if (len < 9) {
|
||||
return "unknown";
|
||||
@@ -252,7 +276,7 @@ static const char *classify_legic_card(const uint8_t *dump, uint16_t len) {
|
||||
return "IAM";
|
||||
}
|
||||
|
||||
if ((dump[7] & 0x0F) == 0x0F && dump[8] == 0xFF) {
|
||||
if (is_kgh_card(dump, len)) {
|
||||
return "KGH";
|
||||
}
|
||||
|
||||
@@ -519,7 +543,11 @@ static int read_badge_from_card(uint32_t *badge_out) {
|
||||
dump[i] ^= crc;
|
||||
}
|
||||
|
||||
bool ok = decode_badge_bcd(&dump[31], badge_out);
|
||||
bool is_kgh = is_kgh_card(dump, datalen);
|
||||
bool ok = is_kgh && decode_badge_bcd(&dump[31], badge_out);
|
||||
if (!is_kgh) {
|
||||
fprintf(stderr, "not a supported KGH card\n");
|
||||
}
|
||||
free(dump);
|
||||
g_printAndLog = prev_print;
|
||||
return ok ? 0 : 1;
|
||||
@@ -563,7 +591,7 @@ int main(int argc, char *argv[]) {
|
||||
legic_read_result_t res;
|
||||
if (read_legic_dump(&res, verbose)) {
|
||||
uint8_t stamp[4] = {0};
|
||||
if (extract_stamp(res.dump, res.len, stamp)) {
|
||||
if (is_kgh_card(res.dump, res.len) && extract_stamp(res.dump, res.len, stamp)) {
|
||||
if (has_output) {
|
||||
if (save_stamp_file(output_file, stamp)) {
|
||||
rc = EXIT_SUCCESS;
|
||||
@@ -574,6 +602,8 @@ int main(int argc, char *argv[]) {
|
||||
printf("%02X%02X%02X%02X\n", stamp[0], stamp[1], stamp[2], stamp[3]);
|
||||
rc = EXIT_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "not a supported KGH card\n");
|
||||
}
|
||||
free_legic_read_result(&res);
|
||||
} else if (verbose) {
|
||||
@@ -614,7 +644,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
uint8_t dump[35] = {0};
|
||||
build_migration_dump(badge, stamp, dump, sizeof(dump));
|
||||
if (legic_migrate_dump(dump, sizeof(dump), true, (const uint8_t[2]){0x60, 0xEA}, true) == PM3_SUCCESS) {
|
||||
if (legic_migrate_dump(dump, sizeof(dump), true, (const uint8_t[2]) {0x60, 0xEA}, true) == PM3_SUCCESS) {
|
||||
rc = EXIT_SUCCESS;
|
||||
} else {
|
||||
fprintf(stderr, "failed to write card\n");
|
||||
Reference in New Issue
Block a user