doc(sign): improve README and add examples (#5620)

Co-authored-by: Maijin <maijin21@gmail.com>
This commit is contained in:
Maijin 2025-12-16 02:57:59 +08:00 committed by GitHub
parent 0321748674
commit 3cd0d5d640
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 281 additions and 0 deletions

View file

@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2025 Maijin <Maijin21@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
/**
* Example: Creating a FLIRT signature from a pattern
*
* This example demonstrates the structure of FLIRT nodes
* and how to create a simple .pat signature string manually.
*/
#include <rz_flirt.h>
#include <rz_util.h>
#include <stdio.h>
int main(int argc, char **argv) {
printf("=== RzSign Create Example ===\n\n");
// Demonstrate how a .pat signature is structured
printf("A .pat signature line has this format:\n");
printf(" <pattern> <pattern_len> <crc16> <func_size> <symbols>\n\n");
// Example: Creating a simple signature for a function
// Pattern bytes: 55 89 E5 83 EC (push ebp; mov ebp, esp; sub esp, ...)
// With variant bytes: 55 89 E5 83 EC .. (last byte is variable)
const char *example_pattern = "5589E583EC..";
const char *func_name = "my_function";
ut8 pattern_len = 0x00;
ut16 crc16 = 0x0000;
ut32 func_size = 0x40; // 64 bytes
printf("Building signature for function '%s':\n", func_name);
printf(" Pattern bytes: 55 89 E5 83 EC ..\n");
printf(" Pattern len: 0x%02X\n", pattern_len);
printf(" CRC16: 0x%04X\n", crc16);
printf(" Function size: 0x%04X (%u bytes)\n\n", func_size, func_size);
// Generate the .pat line
printf("Generated .pat signature:\n");
printf("--------------------------------\n");
printf("%s %02X %04X %04X :0000 %s\n",
example_pattern, pattern_len, crc16, func_size, func_name);
printf("---\n");
printf("--------------------------------\n\n");
// Parse it back to verify
const char *pat_content = "5589E583EC.. 00 0000 0040 :0000 my_function\n---\n";
RzBuffer *buf = rz_buf_new_with_bytes((const ut8 *)pat_content, strlen(pat_content));
if (!buf) {
fprintf(stderr, "Failed to create buffer\n");
return 1;
}
RzFlirtInfo info = { 0 };
RzFlirtNode *node = rz_sign_flirt_parse_string_pattern_from_buffer(buf, RZ_FLIRT_NODE_OPTIMIZE_NONE, &info);
rz_buf_free(buf);
if (node) {
printf("Verification: Parsed signature successfully!\n");
printf(" File type: %s\n", info.type == RZ_FLIRT_FILE_TYPE_PAT ? "PAT" : "Unknown");
printf(" Modules: %u\n", info.u.pat.n_modules);
rz_sign_flirt_info_fini(&info);
rz_sign_flirt_node_free(node);
} else {
fprintf(stderr, "Failed to parse signature\n");
}
printf("\n=== Done ===\n");
return 0;
}

View file

@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: 2025 Maijin <Maijin21@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
/**
* Example: Parsing and matching a FLIRT signature
*
* This example demonstrates how to parse a .pat format
* signature string and count the number of patterns/modules.
*/
#include <rz_flirt.h>
#include <rz_util.h>
#include <stdio.h>
// A simple .pat signature for testing
static const char *test_pat =
"5589E583EC..894DF8....................C745FC00000000 00 0000 0040 :0000 test_function\n"
"---\n";
int main(int argc, char **argv) {
printf("=== RzSign Match Example ===\n\n");
// Create a buffer from the test pattern
RzBuffer *pat_buf = rz_buf_new_with_bytes((const ut8 *)test_pat, strlen(test_pat));
if (!pat_buf) {
fprintf(stderr, "Failed to create buffer\n");
return 1;
}
printf("Parsing .pat signature:\n%s\n", test_pat);
// Parse the pattern
RzFlirtInfo info = { 0 };
RzFlirtNode *node = rz_sign_flirt_parse_string_pattern_from_buffer(pat_buf, RZ_FLIRT_NODE_OPTIMIZE_NONE, &info);
rz_buf_free(pat_buf);
if (!node) {
fprintf(stderr, "Failed to parse pattern\n");
return 1;
}
printf("Parsing successful!\n");
printf("File type: %s\n", info.type == RZ_FLIRT_FILE_TYPE_PAT ? "PAT" : "Unknown");
printf("Number of modules: %u\n", info.u.pat.n_modules);
// Count nodes
ut32 node_count = rz_sign_flirt_node_count_nodes(node);
printf("Total nodes in tree: %u\n", node_count);
// Verify structure
if (node->child_list && rz_list_length(node->child_list) > 0) {
RzFlirtNode *child = rz_list_first(node->child_list);
if (child && child->module_list && rz_list_length(child->module_list) > 0) {
RzFlirtModule *module = rz_list_first(child->module_list);
if (module && module->public_functions && rz_list_length(module->public_functions) > 0) {
RzFlirtFunction *func = rz_list_first(module->public_functions);
printf("\nFirst function in signature:\n");
printf(" Name: %s\n", func->name);
printf(" Offset: 0x%04x\n", func->offset);
printf(" Is local: %s\n", func->is_local ? "yes" : "no");
}
}
}
rz_sign_flirt_info_fini(&info);
rz_sign_flirt_node_free(node);
printf("\n=== Done ===\n");
return 0;
}