Compare commits

...

10 Commits

Author SHA1 Message Date
gbrochar 00ef44ac08 fix: leaks 2024-09-06 21:42:55 +02:00
gbrochar 8e6dec0237 refacto: get_code_cave + algo name 2024-09-06 21:26:35 +02:00
gbrochar f163f8f81a diverse fixes and polish 2024-09-06 15:02:02 +02:00
gbrochar 839f1395a3 feat: banner 2024-09-04 13:25:11 +02:00
gbrochar 18358ce36c refacto(xor): opti payload size 2024-09-03 23:57:33 +02:00
gbrochar 77b90650b1 feat: xor payload 2024-09-03 22:14:18 +02:00
gbrochar 7d93440bd1 feat: insert payload ok 2024-08-30 15:10:07 +02:00
gbrochar 7b240b0c11 chore(Makefile): better libs rules 2024-08-27 12:09:07 +02:00
gbrochar b16dd2c39d chore: prettier Makefile 2024-08-27 11:43:26 +02:00
gbrochar e487bff7ac chore: Makefile 2024-08-27 10:43:56 +02:00
96 changed files with 873 additions and 3756 deletions

4
.gitignore vendored
View File

@ -1,7 +1,3 @@
*.o
*.a
woody_woodpacker
woody
asm
payload
print

View File

@ -1,44 +1,65 @@
NAME = woody_woodpacker
NAME = woody_woodpacker
SRCS_PATH = srcs/
SRC_FILE = main.c \
woody_woodpacker.c \
error.c \
fetch.c \
check_ident.c \
xor_mode.c \
debug_mode.c \
SRCS = $(SRCS_PATH)main.c \
$(SRCS_PATH)utils.c \
$(SRCS_PATH)payload.c \
$(SRCS_PATH)woody32.c \
$(SRCS_PATH)woody64.c \
$(SRCS_PATH)encrypt.c
OBJ_FILE = $(SRC_FILE:.c=.o)
INC_FILE = woody.h \
OBJS = ${SRCS:.c=.o}
SRC_DIR = src/
OBJ_DIR = obj/
INC_DIR = inc/
SRC = $(addprefix $(SRC_DIR), $(SRC_FILE))
OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILE))
INC = $(addprefix $(INC_DIR), $(INC_FILE))
CC = gcc
CC = gcc
CFLAGS = -Wall -Werror -Wextra
RM = rm -f
LIB = ft_printf/libftprintf.a
LIBFT_FLAGS = ft_printf/libftprintf.a
GREEN = \033[32m
RED = \033[31m
ORANGE = \033[33m
PURPLE = \033[35m
CYAN = \033[36m
WHITE = \033[0m
CFLAGS = -Wall -Wextra -Werror
all: $(NAME)
all: ${NAME}
$(NAME): $(LIB) $(OBJ) $(INC)
@$(CC) $(CFLAGS) $(OBJ) $(LIB) -o $(NAME)
@echo -e "$(GREEN)[OK]$(WHITE) $(NAME)"
.c.o:
${CC} ${INCLUDES} ${DEFINES} ${CFLAGS} -c $< -o $@
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(INC)
@if [ ! -d ./obj ]; then \
mkdir -p ./obj; \
fi;
@$(CC) $(CFLAGS) -I $(INC_DIR) -I ft_printf/inc -o $@ -c $<
@echo -e "$(CYAN)[CC]$(WHITE) $(<:$(SRC_DIR)%=%)"
$(NAME): ${OBJS}
make -C ft_printf
${CC} ${OBJS} ${LIBFT_FLAGS} -o ${NAME}
$(LIB):
@echo -e "$(PURPLE)[MAKE]$(WHITE) ft_printf"
@make --no-print-directory -C ft_printf
clean:
make -C ft_printf clean
${RM} ${OBJS}
@make --no-print-directory -C ft_printf clean
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
fclean:
make -C ft_printf fclean
make clean
${RM} ${NAME}
@make --no-print-directory -C ft_printf fclean
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
@echo -e "$(RED)[DELETE]$(WHITE) $(NAME)"
@rm -f $(NAME)
re: fclean
make all
re: fclean all
.PHONY : all clean fclean re
.PHONY: all clean fclean re

5
README
View File

@ -1,5 +0,0 @@
Transform payload code in hexa :
nasm -f elf64 -o print.o print.s && ld -o print print.o && nasm -f bin -o payload print.s && hexdump -v -e '"\\\x\" 1/1 "%02x"' payload
To get it in the clipboad directly append :
| xclip -sel clip to directly

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Woody Woodpacker
Woody Woodpacker is a simple ELF packer that will encrypt the text section of an ELF program and add a payload that will write "....WOODY...." and decrypt the text section before executing it normally.

26
assets/debug_mode.s Normal file
View File

@ -0,0 +1,26 @@
bits 64
global _start
_start:
push rbp
push rsp
push rax
push rdx
push rsi
push rdi
mov rdi, 1
lea rsi, [rel msg]
mov rdx, 14
mov rax, 1
syscall
pop rdi
pop rsi
pop rdx
pop rax
pop rsp
pop rbp
jmp 0xdadadada
msg db "....WOODY....",10

149
assets/rsa.s Normal file
View File

@ -0,0 +1,149 @@
bits 64
global _start
_start:
push rbp
push rsp
push rbx
push r12
push r13
push r14
push r15
push rax
push rcx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
mov rdi, 1
lea rsi, [rel msg]
mov rbx, rsi
sub rbx, qword [rel text_section] ;text_section address because of this and that
mov r8, qword [rel section_size] ;text_section size
shr r8, 2
inc r8
mov r9, 0 ;increment register
mov r10, 0 ;increment register
xor r10, r10
xor r13, r13
mov r13d, dword [rel private_key]
xor r12, r12
mov r12d, dword [rel private_key + 4]
;shr r12, 32
push r13 ; push rsa.d
push r12 ; push rsa.n
jmp decrypt_loop
; rbx is adress of text(encrypted) section
; r8 is section size
; r9 is index
; rax is cypher that needs to be converted to message
; dword [rsp + 16] is rsa.d
; dword [rsp + 8] is rsa.n
; qword [rsp] is cypher backup
decrypt_once:
mov r11, 0x100000000
sq_mul_bit_index:
shr r11, 1
mov r12, r11
and r12, qword [rsp + 16]
jz sq_mul_bit_index
sq_mul_loop:
; check if pow is zero
shr r11, 1
cmp r11, 0
je decrypt_loop2
; square ...
mul rax,
; modulo n ...
mov r13, qword [rsp + 8]
xor rdx, rdx
div r13
mov rax, rdx
; ... and multiply
mov r12, r11
and r12, qword [rsp + 16]
cmp r12, 0
je sq_mul_loop
mov r13, qword [rsp]
mul r13
; modulo n ...
mov r13, qword [rsp + 8]
xor rdx, rdx
div r13
mov rax, rdx
; end of loop
jmp sq_mul_loop
decrypt_loop:
cmp r8, r10
je end_decrypt
xor rax, rax
mov eax, dword [rbx + r9]
push rax
;push r10
jmp decrypt_once
decrypt_loop2:
sub rax, 42 ; remove 42 of result (avoid 0 values)
sub rax, r10 ; remove index of result (caesar like cypher so 0/42 values are differents)
; unpadding and write back here
mov dword [rbx + r9], 0
mov r15, r10
shr r15, 5
shl r15, 2
mov rcx, r10
shl rcx, 59
shr rcx, 59
inc rcx
shl rax, cl
mov r14, r9
sub r14, r15
add [rbx + r14], eax
shr rax, 32
cmp r9, 0
je first_block_skip
add [rbx + r14 - 4], eax
first_block_skip:
; unpadding and write back here
pop rax
add r9, 4
inc r10
jmp decrypt_loop
end_decrypt:
mov rdx, 14
mov rax, 1
syscall
pop r12 ; pop rsa.n
pop r12 ; pop rsa.d
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rax
pop r15
pop r14
pop r13
pop r12
pop rbx
pop rsp
pop rbp
jmp 0xdadadada ; this needs to be just before that
msg db "....WOODY....",10 ; that needs to be just after this
text_section dq 0xbabababababababa
section_size dq 0xcacacacacacacaca
private_key dq 0xabcdefabcdefabcd

21
assets/woody.ans Normal file
View File

@ -0,0 +1,21 @@
                   ..*************..***.                                       
               .***************,***.**.   *.                                   
           *****************.*****,****      .                                 
       .   .****************.***.      .       .                               
        .********************.***          ./.  //                             
      .***************************          /.// .###                       ...
    .******************************. //.//   .../.##.                 .(##//.  
   .******..  .************(##########(.../.  ##############...,..####.//.     
  ,**.                   #######...,.##.####(######################..          
 ..                      .#######.,,,,,,,.#####################.               
                           .(########,,,,,,,,,,,.#......,                      
                                 ..##.#.#####..#.                              
                                       .##.###.                                
 _ _ _____ _____ ____ _ _
( \/\/ )( _ )( _ )( _ \( \/ )
) ( )(_)( )(_)( )(_) )\ /
(__/\__)(_____)(_____)(____/ (__)
 _ _ _____ _____ ____ ____ __ ___ _ _ ____ ____
( \/\/ )( _ )( _ )( _ \( _ \ /__\ / __)( )/ )( ___)( _ \
) ( )(_)( )(_)( )(_) ))___//(__)\( (__ ) ( )__) ) /
(__/\__)(_____)(_____)(____/(__) (__)(__)\___)(_)\_)(____)(_)\_)

57
assets/xor.s Normal file
View File

@ -0,0 +1,57 @@
bits 64
global _start
_start:
push rax
push rcx
push rdx
push rsi
push rdi
lea rdi, [rel _start]
sub rdi, qword [rel load_ptr]
mov rsi, qword [rel load_size]
mov rdx, qword [rel private_key]
decrypt_last_block:
; rcx = 8 * (8 - load_size % 8)
; Then crop the private key by rcx bits
; That's to decrypt the end of the section in case the section size
; isn't a multiple of 64 bits
mov rcx, rsi
not rcx
and rcx, 7
inc rcx
shl rcx, 3
mov rax, rdx
shl rax, cl
shr rax, cl
; make section size a multiple of 64bits with this and
and rsi, 0xfffffffffffffff8
xor [rdi + rsi], rax
decrypt_whole_blocks:
sub rsi, 8
cmp rsi, -8
je end_decrypt
xor [rdi + rsi], rdx
jmp decrypt_whole_blocks
end_decrypt:
lea rsi, [rel msg]
mov rdi, 1
mov rdx, 14
mov rax, 1
syscall
pop rdi
pop rsi
pop rdx
pop rcx
pop rax
jmp 0xdadadada ; this needs to be just before that
msg db "....WOODY....",10 ; that needs to be just after this
load_ptr dq 0xbabababababababa
load_size dq 0xcacacacacacacaca
private_key dq 0xabcdefabcdefabcd

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +1,70 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: pbonilla <eirodeis.lepnj@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2021/01/18 18:08:51 by pbonilla #+# #+# #
# Updated: 2021/03/12 12:27:09 by pbonilla ### ########.fr #
# #
# **************************************************************************** #
NAME = libftprintf.a
LIBFT = ./libft/libft.a
SRC_FILE = ft_printf.c \
ft_parser.c \
ft_int_case.c \
ft_char_case.c \
ft_str_case.c \
ft_ui_case.c \
ft_x_case.c \
ft_ptr_case.c \
ft_percent_case.c \
ft_printf_memset.c \
NAME = libftprintf.a
OBJ_FILE = $(SRC_FILE:.c=.o)
SRCS_PATH = srcs/
INC_FILE = ft_printf.h \
SRCS = $(SRCS_PATH)ft_printf.c \
$(SRCS_PATH)ft_parser.c \
$(SRCS_PATH)ft_int_case.c \
$(SRCS_PATH)ft_char_case.c \
$(SRCS_PATH)ft_str_case.c \
$(SRCS_PATH)ft_ui_case.c \
$(SRCS_PATH)ft_x_case.c \
$(SRCS_PATH)ft_ptr_case.c \
$(SRCS_PATH)ft_percent_case.c \
$(SRCS_PATH)ft_printf_memset.c \
SRC_DIR = src/
OBJ_DIR = obj/
INC_DIR = inc/
SRC = $(addprefix $(SRC_DIR), $(SRC_FILE))
OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILE))
INC = $(addprefix $(INC_DIR), $(INC_FILE))
OBJS = ${SRCS:.c=.o}
CC = gcc
CFLAGS = -Wall -Werror -Wextra
CC = gcc
LIB = libft/libft.a
RM = rm -f
GREEN = \033[32m
RED = \033[31m
ORANGE = \033[33m
PURPLE = \033[35m
CYAN = \033[36m
WHITE = \033[0m
all: $(NAME)
CFLAGS = -Wall -Wextra -Werror
$(NAME): $(LIB) $(OBJ) $(INC)
@cp $(LIB) $(NAME)
@ar -rcs $(NAME) $(OBJ)
@ranlib $(NAME)
@echo -e "$(GREEN)[OK]$(WHITE) $(NAME)"
INCLUDES = -I libft
$(OBJ_DIR)%.o: $(SRC_DIR)%.c libft/ $(INC)
@if [ ! -d ./obj ]; then \
mkdir -p ./obj; \
fi;
@$(CC) $(CFLAGS) -I $(INC_DIR) -I libft/inc -o $@ -c $<
@echo -e "$(CYAN)[CC]$(WHITE) $(<:$(SRC_DIR)%=%)"
all: ${NAME}
.c.o:
${CC} ${INCLUDES} ${DEFINES} ${CFLAGS} -c $< -o $@
$(NAME): ${OBJS}
$(MAKE) bonus -C ./libft
cp libft/libft.a $(NAME)
ar -rcs $(NAME) $(OBJS)
ranlib $(NAME)
$(LIB):
@echo -e "$(PURPLE)[MAKE]$(WHITE) libft"
@make --no-print-directory -C ./libft
clean:
$(MAKE) clean -C ./libft
${RM} ${OBJS}
@make --no-print-directory -C libft clean
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
fclean: clean
$(MAKE) fclean -C ./libft
${RM} ${NAME}
fclean:
@make --no-print-directory -C libft fclean
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
@echo -e "$(RED)[DELETE]$(WHITE) $(NAME)"
@rm -f $(NAME)
re: fclean all
.PHONY : all clean fclean re
.PHONY: all clean fclean re

View File

@ -13,7 +13,7 @@
#ifndef FT_PRINTF_H
# define FT_PRINTF_H
# include "../libft/libft.h"
# include "../libft/inc/libft.h"
# include <stdarg.h>
# include <stdio.h>

View File

@ -1,103 +1,102 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: pbonilla <eirodeis.lepnj@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2021/01/18 18:08:51 by pbonilla #+# #+# #
# Updated: 2021/02/07 14:20:29 by pbonilla ### ########.fr #
# #
# **************************************************************************** #
NAME = libft.a
NAME = libft.a
SRC_FILE = ft_atoi.c \
ft_toupper.c \
ft_bzero.c \
ft_isalnum.c \
ft_tolower.c \
ft_memcpy.c \
ft_memccpy.c \
ft_memmove.c \
ft_memset.c \
ft_memchr.c \
ft_memcmp.c \
ft_strlcat.c \
ft_strnstr.c \
ft_strlcat.c \
ft_strlen.c \
ft_strchr.c \
ft_strrchr.c \
ft_isalpha.c \
ft_isascii.c \
ft_strlcpy.c \
ft_strncmp.c \
ft_isdigit.c \
ft_isprint.c \
ft_toupper.c \
ft_bzero.c \
ft_strdup.c \
ft_strnstr.c \
ft_strnstr_nullterminated.c \
ft_calloc.c \
ft_substr.c \
ft_strjoin.c \
ft_u_itoa.c \
ft_itoa.c \
ft_strmapi.c \
ft_putchar_fd.c \
ft_putstr_fd.c \
ft_putnbr_fd.c \
ft_putendl_fd.c \
ft_strtrim.c \
ft_split.c \
ft_u_convert.c \
ft_convert_base.c \
ft_revert_int.c \
ft_lstnew.c \
ft_lstadd_front.c \
ft_lstsize.c \
ft_lstlast.c \
ft_lstadd_back.c \
ft_lstdelone.c \
ft_lstclear.c \
ft_lstiter.c \
ft_lstmap.c \
SRCS_PATH = ./
OBJ_FILE = $(SRC_FILE:.c=.o)
SRCS = $(SRCS_PATH)ft_atoi.c \
$(SRCS_PATH)ft_toupper.c \
$(SRCS_PATH)ft_bzero.c \
$(SRCS_PATH)ft_isalnum.c \
$(SRCS_PATH)ft_tolower.c \
$(SRCS_PATH)ft_memcpy.c \
$(SRCS_PATH)ft_memccpy.c \
$(SRCS_PATH)ft_memmove.c \
$(SRCS_PATH)ft_memset.c \
$(SRCS_PATH)ft_memchr.c \
$(SRCS_PATH)ft_memcmp.c \
$(SRCS_PATH)ft_strlcat.c \
$(SRCS_PATH)ft_strnstr.c \
$(SRCS_PATH)ft_strlcat.c \
$(SRCS_PATH)ft_strlen.c \
$(SRCS_PATH)ft_strchr.c \
$(SRCS_PATH)ft_strrchr.c \
$(SRCS_PATH)ft_isalpha.c \
$(SRCS_PATH)ft_isascii.c \
$(SRCS_PATH)ft_strlcpy.c \
$(SRCS_PATH)ft_strncmp.c \
$(SRCS_PATH)ft_isdigit.c \
$(SRCS_PATH)ft_isprint.c \
$(SRCS_PATH)ft_toupper.c \
$(SRCS_PATH)ft_bzero.c \
$(SRCS_PATH)ft_strdup.c \
$(SRCS_PATH)ft_strnstr.c \
$(SRCS_PATH)ft_strnstr_nullterminated.c \
$(SRCS_PATH)ft_calloc.c \
$(SRCS_PATH)ft_substr.c \
$(SRCS_PATH)ft_strjoin.c \
$(SRCS_PATH)ft_u_itoa.c \
$(SRCS_PATH)ft_itoa.c \
$(SRCS_PATH)ft_strmapi.c \
$(SRCS_PATH)ft_putchar_fd.c \
$(SRCS_PATH)ft_putstr_fd.c \
$(SRCS_PATH)ft_putnbr_fd.c \
$(SRCS_PATH)ft_putendl_fd.c \
$(SRCS_PATH)ft_strtrim.c \
$(SRCS_PATH)ft_split.c \
$(SRCS_PATH)ft_u_convert.c \
$(SRCS_PATH)ft_convert_base.c \
$(SRCS_PATH)ft_revert_int.c \
INC_FILE = libft.h
SRC_DIR = src/
OBJ_DIR = obj/
INC_DIR = inc/
SRC = $(addprefix $(SRC_DIR), $(SRC_FILE))
OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILE))
INC = $(addprefix $(INC_DIR), $(INC_FILE))
BONUS = $(SRCS_PATH)ft_lstnew.c \
$(SRCS_PATH)ft_lstadd_front.c \
$(SRCS_PATH)ft_lstsize.c \
$(SRCS_PATH)ft_lstlast.c \
$(SRCS_PATH)ft_lstadd_back.c \
$(SRCS_PATH)ft_lstdelone.c \
$(SRCS_PATH)ft_lstclear.c \
$(SRCS_PATH)ft_lstiter.c \
$(SRCS_PATH)ft_lstmap.c \
CC = gcc
CFLAGS = -Wall -Werror -Wextra
OBJS = ${SRCS:.c=.o}
GREEN = \033[32m
RED = \033[31m
ORANGE = \033[33m
CYAN = \033[36m
WHITE = \033[0m
BONUS_OBJS = $(BONUS:.c=.o)
all: $(NAME)
CC = gcc
$(NAME): $(OBJ) $(INC)
@ar rc $(NAME) $(OBJ)
@ranlib $(NAME)
@echo -e "$(GREEN)[OK]$(WHITE) $(NAME)"
RM = rm -f
CFLAGS = -Wall -Wextra -Werror
$(NAME): $(OBJS)
ar rc $(NAME) $(OBJS)
ranlib $(NAME)
all: $(NAME)
.c.o:
${CC} ${INCLUDES} ${DEFINES} ${CFLAGS} -c $< -o $@
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(INC)
@if [ ! -d ./obj ]; then \
mkdir -p ./obj; \
fi;
@$(CC) $(CFLAGS) -I $(INC_DIR) -o $@ -c $<
@echo -e "$(CYAN)[CC]$(WHITE) $(<:$(SRC_DIR)%=%)"
clean:
rm -rf $(OBJS) $(BONUS_OBJS)
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
fclean: clean
rm -rf $(NAME)
fclean:
@echo -e "$(ORANGE)[CLEAN]$(WHITE) $(NAME)"
@rm -rf $(OBJ_DIR)
@echo -e "$(RED)[DELETE]$(WHITE) $(NAME)"
@rm -f $(NAME)
re: fclean all
bonus: $(OBJS) $(BONUS_OBJS)
ar rc $(NAME) $(OBJS) $(BONUS_OBJS)
ranlib $(NAME)
.PHONY : all clean fclean re bonus
.PHONY: all clean fclean re

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *ft_char_case(t_param *param, int i)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *fill_s_int(char *s, int len, char *s_i, t_param *param)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
t_param ft_init_param(void)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *ft_percent_case(t_param *param)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
int ft_print_param(t_param *param, va_list args, char **buff)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
void *ft_printf_memset(void *s, size_t n, t_param *param)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
int zero_case(t_param *param, unsigned long long i)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *fill_s_str(char *s, int len, char *s_arg, t_param *param)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *fill_s_uint(char *s, int len, char *s_ui, t_param *param)
{

View File

@ -10,7 +10,7 @@
/* */
/* ************************************************************************** */
#include "../includes/ft_printf.h"
#include "ft_printf.h"
char *fill_s_x(int len, int save, char *s_x, t_param *param)
{

View File

@ -1 +1 @@
nasm -f elf64 -o print.o print.s && ld -o print print.o && nasm -f bin -o payload print.s && hexdump -v -e '"\\\x\" 1/1 "%02x"' payload
nasm -f elf64 -o payload.o $1 && ld -o a.out payload.o && nasm -f bin -o payload $1 && hexdump -v -e '"\\\x\" 1/1 "%02x"' payload && rm -rf payload.o payload a.out

51
inc/woody.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef WOODY_H
# define WOODY_H
# include "ft_printf.h"
# include <stdio.h>
# include <fcntl.h>
# include <sys/mman.h>
# include <elf.h>
# define RET_ERR 1
# define RET_OK 0
# define PL_XOR 0
# define PL_RSA 1
# define PL_DEBUG 2
typedef struct s_map {
void *data;
off_t size;
} t_map;
typedef struct s_payload64 {
int (*encrypt)(t_map, void *, Elf64_Phdr);
int (*gen_key)(void **);
char *algo_name;
size_t jump_offset;
size_t woody_offset;
size_t load_ptr_offset;
size_t load_size_offset;
size_t private_key_offset;
size_t len;
unsigned char *data;
} t_payload64;
int woody_woodpacker(char *path);
void *fetch(t_map map, size_t offset, size_t len);
int wdy_error(char *str);
int wdy_perror(char *path);
int check_ident(t_map file);
t_payload64 get_debug_payload64(void);
int gen_key_xor(void **key);
int encrypt_xor(t_map file, void *key_ptr, Elf64_Phdr load_segment);
t_payload64 get_xor_payload64(void);
#endif

View File

@ -1,81 +0,0 @@
#ifndef WOODY_H
#define WOODY_H
#include "../ft_printf/includes/ft_printf.h"
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <elf.h>
#include <stdint.h>
#define JUMP "\xe9"
#define WOODY "....WOODY...."
#define JUMP_VALUE "\xda\xda\xda"
#define TEXT_OFFSET "\xba\xba\xba\xba\xba\xba\xba\xba"
#define SECTION_SIZE "\xca\xca\xca\xca\xca\xca\xca\xca"
typedef struct payload
{
char *payload;
int len;
} t_payload;
typedef struct elf32
{
Elf32_Ehdr *Ehdr;
Elf32_Phdr *Phdr;
Elf32_Shdr *Shdr;
Elf32_Shdr *text_section;
} t_elf32;
typedef struct elf64
{
Elf64_Ehdr *Ehdr;
Elf64_Phdr *Phdr;
Elf64_Shdr *Shdr;
Elf64_Shdr *text_section;
} t_elf64;
typedef struct elf_content
{
long unsigned int file_size;
char *file_path;
char *file;
t_elf32 *elf32;
t_elf64 *elf64;
} t_elf_content;
// utils.c
void *fetch(char *file, unsigned long file_size, unsigned long offset_to_data, unsigned long supposed_data_size);
int ft_put_error(char *str);
char *get_string(char *str, char *end_file);
int get_symbols_count(int sh_size, int sh_entsize);
char *get_section_name(t_elf_content *woody, int section_index);
int elf_magic_numbers(char *str);
// payload.c
t_payload *get_payload();
int insert_payload(t_elf_content *woody, t_payload *payload, size_t payload_position, unsigned int e_entry, unsigned int p_offset, unsigned int p_memsz);
// woody32.c
int get_elf_sections32(t_elf_content *woody);
int inject32(t_elf_content *woody);
// woody64.c
int get_elf_sections64(t_elf_content *woody);
int inject64(t_elf_content *woody);
// encrypt.c
void encrypt(char *file, unsigned long int offset, unsigned long int size);
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

37
print.s
View File

@ -1,37 +0,0 @@
bits 64
global _start
_start:
push rax
push rdi
push rsi
push rdx
mov rdi, 1
lea rsi, [rel msg]
mov rax, rsi
sub rax, qword [rel text_section] ;text_section address
mov r8, qword [rel section_size] ;text_section size
mov r9, 0 ;increment register
xor r10, r10
encrypt:
cmp r8, r9
je end_encrypt
movzx r10, byte[rax + r9]
inc r10b ;rot + 1
mov byte[rax + r9], r10b
inc r9
jmp encrypt
end_encrypt:
mov rdx, 14
mov rax, 1
syscall
pop rdx
pop rsi
pop rdi
pop rax
jmp 0xdadadada
msg db "....WOODY....",10
text_section dq 0xbabababababababa
section_size dq 0xcacacacacacacaca

View File

@ -1,412 +0,0 @@
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
return (0);
}

View File

@ -1,332 +0,0 @@
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
return (0);
}

View File

@ -1,6 +1,7 @@
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
return (0);
int
main(void) {
ft_printf("Hello, World!\n");
return (0x0);
}

37
src/check_ident.c Normal file
View File

@ -0,0 +1,37 @@
#include "woody.h"
int ident_error(void) {
return wdy_error("file format not recognized (invalid ELF Ident)");
}
int is_valid_elf_magic_number(char *ident) {
return !ft_strncmp(ident, ELFMAG, SELFMAG);
}
int is_valid_arch(char arch) {
return arch == ELFCLASS64 || arch == ELFCLASS32;
}
int is_valid_data_format(unsigned char data_format) {
return data_format == ELFDATA2MSB || data_format == ELFDATA2LSB;
}
int is_valid_version(unsigned char version) {
return version == EV_CURRENT;
}
int check_ident(t_map file) {
char *ident = (char *)fetch(file, 0, EI_NIDENT);
if (!ident) {
return ident_error();
}
if (!is_valid_elf_magic_number(ident)
|| !is_valid_arch(ident[EI_CLASS])
|| !is_valid_data_format(ident[EI_DATA])
|| !is_valid_version(ident[EI_VERSION])) {
return ident_error();
}
return RET_OK;
}

18
src/debug_mode.c Normal file
View File

@ -0,0 +1,18 @@
#include "woody.h"
t_payload64 get_debug_payload64(void) {
t_payload64 payload;
payload.algo_name = ft_strdup("debug");
payload.len = 55;
payload.jump_offset = 37;
payload.encrypt = NULL;
payload.data = malloc(payload.len * sizeof(unsigned char));
ft_memcpy(payload.data,
"\x55\x54\x50\x52\x56\x57\xbf\x01\x00\x00\x00\x48\x8d\x35\x17\x00"
"\x00\x00\xba\x0e\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\x5f\x5e"
"\x5a\x58\x5c\x5d\xe9\xb1\xda\xda\xda\x2e\x2e\x2e\x2e\x57\x4f\x4f"
"\x44\x59\x2e\x2e\x2e\x2e\x0a",
payload.len);
return payload;
}

11
src/error.c Normal file
View File

@ -0,0 +1,11 @@
#include "woody.h"
int wdy_error(char *str) {
ft_printf("error: %s\n", str);
return RET_ERR;
}
int wdy_perror(char *path) {
perror(path);
return RET_ERR;
}

8
src/fetch.c Normal file
View File

@ -0,0 +1,8 @@
#include "woody.h"
void *fetch(t_map map, size_t offset, size_t len) {
if (offset + len <= (size_t)map.size) {
return map.data + offset;
}
return NULL;
}

22
src/main.c Normal file
View File

@ -0,0 +1,22 @@
#include "woody.h"
void banner(void) {
int fd = open("assets/woody.ans", O_RDONLY);
if (fd == -1) {
ft_printf("warning: can't open banner file\n");
return;
}
char buffer[13149];
ssize_t len = read(fd, buffer, 13149);
write(1, buffer, len);
}
int main(int ac, char **av) {
banner();
if (ac == 2) {
return woody_woodpacker(av[1]);
} else {
ft_printf("usage: %s [filename]\n", av[0]);
}
return RET_OK;
}

187
src/woody_woodpacker.c Normal file
View File

@ -0,0 +1,187 @@
#include "woody.h"
int wdy_get_file(char *path, t_map *file) {
int fd = open(path, O_RDONLY);
if (fd == -1) {
return wdy_perror(path);
}
file->size = lseek(fd, 0, SEEK_END);
if (file->size == -1) {
close(fd);
return wdy_perror(path);
}
file->data = mmap(
NULL,
file->size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE,
fd,
0);
close(fd);
if (file->data == MAP_FAILED) {
return wdy_perror(path);
}
return RET_OK;
}
int pack_elf32(t_map file) {
(void)file;
return wdy_error("ELF needs to be in 64 bits format");
}
int get_load_segment64(
Elf64_Ehdr elf_header,
Elf64_Phdr *program_headers,
Elf64_Phdr **load_segment) {
for (int i = 0; i < elf_header.e_phnum; i++) {
Elf64_Phdr *p_hdr = &program_headers[i];
if (p_hdr->p_type == PT_LOAD
&& p_hdr->p_flags & PF_X
&& p_hdr->p_vaddr <= elf_header.e_entry
&& p_hdr->p_vaddr + p_hdr->p_filesz > elf_header.e_entry) {
*load_segment = p_hdr;
return RET_OK;
}
}
return RET_ERR;
}
int get_code_cave64(t_map file, Elf64_Phdr load_segment, t_map *code_cave) {
size_t page_size = load_segment.p_align;
size_t len = page_size - load_segment.p_filesz % page_size;
size_t offset = load_segment.p_offset + load_segment.p_filesz;
unsigned char *seg = fetch(file, offset, len);
if (!seg) {
return RET_ERR;
}
size_t longest = 0;
size_t longest_i = 0;
for (size_t i = 0; i < len; i++) {
if (seg[i] == 0) {
size_t j = 0;
while (i + j < len && seg[i + j] == 0) {
j++;
}
if (j > longest) {
longest_i = i;
longest = j;
}
i += j;
}
}
code_cave->data = fetch(file, longest_i + offset, longest);
code_cave->size = longest;
return RET_OK;
}
int pack_elf64(t_map file) {
Elf64_Ehdr *elf_header = (Elf64_Ehdr *)fetch(file, 0, sizeof(Elf64_Ehdr));
if (!elf_header) {
return wdy_error("cannot fetch elf header");
}
size_t phdrs_len = elf_header->e_phnum * elf_header->e_phentsize;
Elf64_Phdr *program_headers = fetch(file, elf_header->e_phoff, phdrs_len);
if (!program_headers) {
return wdy_error("cannot fetch program headers table");
}
Elf64_Phdr *load_segment;
if (get_load_segment64(*elf_header, program_headers, &load_segment) == RET_ERR) {
return wdy_error("cannot get load segment");
}
// TODO the whole section below till the end of the function needs
// cleaning and refactoring, better naming also.
// This should go in a separate function regarding encryption if encryption has been requested.
/*
size_t encryption_block_size = 31; // 32 bits and padding...
t_map to_encrypt;
to_encrypt.data = fetch(file, load_segment.p_offset, 0);
// size is a multiple of 31...
to_encrypt.size = load_segment.p_filesz + encryption_block_size - load_segment.p_filesz % encryption_block_size;
*/
t_map code_cave;
if (get_code_cave64(file, *load_segment, &code_cave) == RET_ERR) {
return wdy_error("can't get code cave");
}
t_payload64 payload = get_xor_payload64();
ft_printf("info: using %s algorithm\n", payload.algo_name);
free(payload.algo_name);
// This should fallback to compression algorithm, or smaller payload (eg rsa->xor)
if (payload.len > (size_t)code_cave.size) {
printf("code cave size: %ld (0x%lx) bytes\n", code_cave.size, code_cave.size);
return wdy_error("payload length exceed code cave size");
}
// e_entry because relative to this (where we gonna go)
// code cave start because thats the start of the code
// jump_offset is the index of jump from code cave start
// 4 because jump has a 4 byte operand)
size_t code_cave_start = code_cave.data - file.data;
int jump_value = elf_header->e_entry - code_cave_start - payload.jump_offset - 4;
ft_memcpy(payload.data + payload.jump_offset, &jump_value, sizeof(jump_value));
if (payload.encrypt != NULL) {
uint64_t load_ptr_value = code_cave_start - load_segment->p_offset;
ft_memcpy(payload.data + payload.load_ptr_offset, &load_ptr_value, sizeof(load_ptr_value));
ft_memcpy(payload.data + payload.load_size_offset, &load_segment->p_filesz, sizeof(load_segment->p_memsz));
void *key = NULL;
if (payload.gen_key(&key) != RET_OK) {
return wdy_error("key generation failed");
}
ft_memcpy(payload.data + payload.private_key_offset, key, sizeof(uint64_t));
payload.encrypt(file, key, *load_segment);
free(key);
}
elf_header->e_entry = code_cave.data - file.data;
load_segment->p_filesz += payload.len;
load_segment->p_memsz += payload.len;
load_segment->p_flags |= PF_W | PF_R;
ft_memcpy(code_cave.data, payload.data, payload.len);
free(payload.data);
int fd = open("woody", O_WRONLY | O_CREAT, 0755);
if (fd == -1) {
return wdy_perror("woody");
}
write(fd, file.data, file.size);
munmap(file.data, file.size);
return RET_OK;
}
int pack_elf(t_map file) {
// at this point arch is known to be either ELFCLASS32 or ELFCLASS64
unsigned char arch = ((unsigned char *)file.data)[4];
if (arch == ELFCLASS64) {
return pack_elf64(file);
}
return pack_elf32(file);
}
int woody_woodpacker(char *path) {
t_map file;
if (wdy_get_file(path, &file) == RET_ERR) {
return RET_ERR;
}
if (check_ident(file) == RET_ERR) {
return RET_ERR;
}
int ret = pack_elf(file);
if (ret == RET_OK) {
ft_printf("successfully woody woodpacked %s\n", path);
} else {
ft_printf("error: can't woody woodpack %s\n", path);
}
return ret;
}

79
src/xor_mode.c Normal file
View File

@ -0,0 +1,79 @@
#include "woody.h"
int gen_key_xor(void **key) {
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
return wdy_perror("/dev/urandom");
}
*key = malloc(sizeof(uint64_t));
if (!key) {
return wdy_perror("malloc");
}
if (read(fd, *key, sizeof(uint64_t)) != 8) {
return wdy_perror("/dev/urandom");
}
close(fd);
return RET_OK;
}
void print_key(uint64_t key) {
uint64_t mask = 0xf000000000000000;
ft_printf("info: private_key: 0x");
for (int i = 60; i >= 0; i -= 4) {
uint64_t print = (key & mask) >> i;
if (print < 10) {
print += '0';
write(1, &print, 1);
}
else {
print += 'a' - 10;
write(1, &print, 1);
}
mask >>= 4;
}
write (1, "\n", 1);
}
int encrypt_xor(t_map file, void *key_ptr, Elf64_Phdr load_segment) {
// TODO try oneliner
uint64_t *tmp = key_ptr;
uint64_t key = *tmp;
print_key(key);
size_t i = 0;
while (i < load_segment.p_filesz >> 3) {
((uint64_t *)file.data)[i + (load_segment.p_offset >> 3)] ^= key;
i++;
}
key <<= (8 - (load_segment.p_filesz % 8)) * 8;
key >>= (8 - (load_segment.p_filesz % 8)) * 8;
((uint64_t *)file.data)[i + (load_segment.p_offset >> 3)] ^= key;
return RET_OK;
}
t_payload64 get_xor_payload64(void) {
t_payload64 payload;
payload.algo_name = ft_strdup("xor");
payload.len = 155;
payload.jump_offset = 113;
payload.load_ptr_offset = 131;
payload.load_size_offset = 139;
payload.private_key_offset = 147;
payload.encrypt = &encrypt_xor;
payload.gen_key = &gen_key_xor;
payload.data = malloc(payload.len * sizeof(unsigned char));
ft_memcpy(payload.data,
"\x50\x51\x52\x56\x57\x48\x8d\x3d\xf4\xff\xff\xff\x48\x2b\x3d\x70"
"\x00\x00\x00\x48\x8b\x35\x71\x00\x00\x00\x48\x8b\x15\x72\x00\x00"
"\x00\x48\x89\xf1\x48\xf7\xd1\x48\x83\xe1\x07\x48\xff\xc1\x48\xc1"
"\xe1\x03\x48\x89\xd0\x48\xd3\xe0\x48\xd3\xe8\x48\x83\xe6\xf8\x48"
"\x31\x04\x37\x48\x83\xee\x08\x48\x83\xfe\xf8\x74\x06\x48\x31\x14"
"\x37\xeb\xf0\x48\x8d\x35\x1b\x00\x00\x00\xbf\x01\x00\x00\x00\xba"
"\x0e\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\x5f\x5e\x5a\x59\x58"
"\xe9\x65\xda\xda\xda\x2e\x2e\x2e\x2e\x57\x4f\x4f\x44\x59\x2e\x2e"
"\x2e\x2e\x0a\xba\xba\xba\xba\xba\xba\xba\xba\xca\xca\xca\xca\xca"
"\xca\xca\xca\xcd\xab\xef\xcd\xab\xef\xcd\xab",
payload.len);
return payload;
}

View File

@ -1,11 +0,0 @@
#include "../includes/woody.h"
void encrypt(char *file, unsigned long int offset, unsigned long int size)
{
size_t i = 0;
while (i < size)
{
file[offset + i] = file[offset + i] - 1;
++i;
}
}

View File

@ -1,127 +0,0 @@
#include "../includes/woody.h"
void free_elf_content(t_elf_content *woody)
{
if (woody->elf32)
free(woody->elf32);
else if (woody->elf64)
free(woody->elf64);
}
int get_elf_file(t_elf_content *woody)
{
int fd;
off_t off;
fd = open(woody->file_path, O_RDONLY);
if (fd < 0)
{
ft_printf("Error: Failed to open \'%s\'\n", woody->file_path);
return EXIT_FAILURE;
}
off = lseek(fd, 0, SEEK_END);
if (off == -1)
{
close(fd);
ft_printf("Error: Failed to read file offset \'%s\'\n", woody->file_path);
return EXIT_FAILURE;
}
woody->file_size = off;
woody->file = mmap(NULL, woody->file_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
if (woody->file == MAP_FAILED)
{
close(fd);
ft_printf("Error: Failed to map file \'%s\'\n", woody->file_path);
return EXIT_FAILURE;
}
close(fd);
return EXIT_SUCCESS;
}
int save_file(char *path, char *file, unsigned long int size)
{
int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0755);
if (fd == -1) {
ft_printf("Error: Failed to create new file \'%s\'\n", path);
return EXIT_FAILURE;
}
if (write(fd, file, size) == -1) {
close(fd);
ft_printf("Error: Failed to write new file \'%s\'\n", path);
return EXIT_FAILURE;
}
close(fd);
return EXIT_SUCCESS;
}
int save_woody(t_elf_content *woody)
{
char *woody_file = malloc(woody->file_size);
if (!woody_file)
return ft_put_error("Allocation error");
ft_memcpy(woody_file, woody->file, woody->file_size);
if (munmap(woody->file, woody->file_size))
return ft_put_error("Umapping error");
int save_error = save_file("woody", woody_file, woody->file_size);
if (save_error)
return save_error;
free(woody_file);
return EXIT_SUCCESS;
}
int main(int ac, char **av)
{
t_elf_content woody = {0};
if (ac != 2)
{
return ft_put_error("Woody_woodpacker take 1 argument\n");
}
woody.file_path = av[1];
int elf_error = get_elf_file(&woody);
if (elf_error)
return elf_error;
if (woody.file_size < sizeof(Elf32_Ehdr) || !elf_magic_numbers(woody.file))
{
ft_printf("Error: \'%s\' is not a valid ELF file\n", woody.file_path);
return EXIT_FAILURE;
}
int elfclass = woody.file[4];
if (elfclass == ELFCLASS32)
{
if (!(woody.elf32 = malloc(sizeof(t_elf32))))
return ft_put_error("Allocation error");
elf_error = get_elf_sections32(&woody);
}
else if (elfclass == ELFCLASS64)
{
if (!(woody.elf64 = malloc(sizeof(t_elf64))))
return ft_put_error("Allocation error");
elf_error = get_elf_sections64(&woody);
}
else
{
elf_error = EXIT_FAILURE;
ft_printf("Error: \'%s\' is not a valid ELF file\n", woody.file_path);
}
if (elf_error)
return elf_error;
int inject_error = -1;
if (elfclass == ELFCLASS32)
{
inject_error = inject32(&woody);
}
else if (elfclass == ELFCLASS64)
{
inject_error = inject64(&woody);
}
if (inject_error)
{
free_elf_content(&woody);
return inject_error;
}
int save_error = save_woody(&woody);
free_elf_content(&woody);
return save_error;
}

View File

@ -1,66 +0,0 @@
#include "../includes/woody.h"
t_payload *get_payload()
{
t_payload *payload = malloc(sizeof(t_payload));
if (!payload)
return NULL;
char buffer[1024];
int fd = open("payload", O_RDONLY);
if (fd == -1) {
ft_put_error("Failed to open payload");
free(payload);
return NULL;
}
payload->len = read(fd, buffer, 1024);
if (payload->len == -1)
{
ft_put_error("Failed to read payload");
free(payload);
close(fd);
return NULL;
}
close(fd);
payload->payload = malloc(sizeof(char) * payload->len);
if (!payload->payload)
{
ft_put_error("Allocation error");
free(payload);
return NULL;
}
ft_memcpy(payload->payload, buffer, payload->len);
return payload;
}
int insert_payload(t_elf_content *woody, t_payload *payload, size_t payload_position, unsigned int e_entry, unsigned int p_offset, unsigned int p_memsz)
{
char *ptr_jmp_value = ft_strnstr_nullterminated(payload->payload, JUMP_VALUE, payload->len);
char *ptr_woody = ft_strnstr_nullterminated(payload->payload, WOODY, payload->len);
char *ptr_text_section = ft_strnstr_nullterminated(payload->payload, TEXT_OFFSET, payload->len);
char *ptr_section_size = ft_strnstr_nullterminated(payload->payload, SECTION_SIZE, payload->len);
if (ptr_jmp_value && ptr_woody && ptr_text_section && ptr_section_size)
{
int32_t woody_index = ptr_woody - payload->payload;
int32_t jmp_index = ptr_jmp_value - sizeof(JUMP) - payload->payload;
int32_t jump_value = ((payload_position + jmp_index + 5) - e_entry) * -1; // 5 = JUMP SIZE (OPCODE + 4 bytes operand)
ft_memcpy(&payload->payload[jmp_index + 1], &jump_value, sizeof(jump_value));
printf("jump_value = %d (%x)\n", jump_value, jump_value);
printf("jmp_index = %d (%x)\n", jmp_index, jmp_index);
printf("payload_position = %ld (%lx)\n", payload_position, payload_position);
printf("e_entry = %d (%x)\n", e_entry, e_entry);
int64_t text_index = ptr_text_section - payload->payload;
int64_t text_value = payload_position - p_offset + woody_index;
ft_memcpy(&payload->payload[text_index], &text_value, sizeof(text_value));
int64_t section_index = ptr_section_size - payload->payload;
int64_t section_value = p_memsz;
ft_memcpy(&payload->payload[section_index], &section_value, sizeof(section_value));
ft_memcpy(woody->file + payload_position, payload->payload, payload->len);
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}

View File

@ -1,40 +0,0 @@
#include "../includes/woody.h"
void *fetch(char *file, unsigned long file_size, unsigned long offset_to_data, unsigned long supposed_data_size)
{
if (file_size > offset_to_data && file_size >= (offset_to_data + supposed_data_size))
return (file + offset_to_data);
return NULL;
}
int elf_magic_numbers(char *str)
{
return (!ft_strncmp(str, ELFMAG, SELFMAG));
}
int get_symbols_count(int sh_size, int sh_entsize)
{
if (sh_size <= 0 || sh_entsize <= 0)
return 0;
return (sh_size / sh_entsize);
}
char *get_string(char *str, char *end_file)
{
char *search_end = str;
while (search_end < end_file)
{
if (*search_end == 0)
return str;
++search_end;
}
return NULL;
}
int ft_put_error(char *str)
{
ft_putstr_fd("Error: ", STDERR_FILENO);
ft_putstr_fd(str, 2);
ft_putstr_fd("\n", STDERR_FILENO);
return EXIT_FAILURE;
}

View File

@ -1,106 +0,0 @@
#include "../includes/woody.h"
int get_load_segment32(t_elf_content *woody, int start, bool executable)
{
t_elf32 *elf = woody->elf32;
for (int i = start; i < elf->Ehdr->e_phnum; i++)
{
if (elf->Phdr[i].p_type == PT_LOAD)
{
if (executable)
{
if (elf->Phdr[i].p_flags & PF_X)
return i;
}
else
return i;
}
}
return -1;
}
int inject32(t_elf_content *woody)
{
t_elf32 *elf = woody->elf32;
t_payload *payload = get_payload();
if (!payload)
return EXIT_FAILURE;
int i = get_load_segment32(woody, 0, true);
int j = get_load_segment32(woody, i + 1, false);
if (i == -1 || j != i + 1)
{
free(payload->payload);
free(payload);
return ft_put_error("PT_LOAD segment missing");
}
size_t code_cave_size = elf->Phdr[j].p_offset - (elf->Phdr[i].p_offset + elf->Phdr[i].p_filesz);
size_t payload_position = elf->Phdr[i].p_offset + elf->Phdr[i].p_filesz;
if (code_cave_size < (size_t)payload->len)
{
free(payload->payload);
free(payload);
return ft_put_error("Unable to insert payload, not enough space for code cave");
}
encrypt(woody->file, elf->Phdr[i].p_offset, elf->Phdr[i].p_memsz);
if (insert_payload(woody, payload, payload_position, elf->text_section->sh_offset, elf->Phdr[i].p_offset, elf->Phdr[i].p_memsz))
{
free(payload->payload);
free(payload);
return ft_put_error("Unable to insert payload, please regenerate it");
}
printf("code_cave_size = %ld (%lx)\n", code_cave_size, code_cave_size);
printf("payload_position = %ld (%lx)\n", payload_position, payload_position);
printf("elf->Phdr[i].p_offset = %d (%x)\n", elf->Phdr[i].p_offset, elf->Phdr[i].p_offset);
printf("elf->Phdr[i].p_filesz = %d (%x)\n", elf->Phdr[i].p_filesz, elf->Phdr[i].p_filesz);
printf("elf->Phdr[j].p_offset = %d (%x)\n", elf->Phdr[j].p_offset, elf->Phdr[j].p_offset);
elf->Phdr[i].p_filesz += payload->len;
elf->Phdr[i].p_memsz += payload->len;
elf->Phdr[i].p_flags = PF_X | PF_W | PF_R;
free(payload->payload);
free(payload);
return EXIT_SUCCESS;
}
int get_elf_sections32(t_elf_content *woody)
{
t_elf32 *elf = woody->elf32;
elf->Ehdr = (Elf32_Ehdr *)fetch(woody->file, woody->file_size, 0, sizeof(Elf32_Ehdr));
if (!elf->Ehdr)
return EXIT_FAILURE;
elf->Phdr = (Elf32_Phdr *)fetch(woody->file, woody->file_size, elf->Ehdr->e_phoff, sizeof(Elf32_Phdr));
if (!elf->Phdr)
return EXIT_FAILURE;
elf->Shdr = (Elf32_Shdr *)fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff, sizeof(Elf32_Shdr));
if (!elf->Shdr || !fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff, elf->Ehdr->e_shnum * sizeof(Elf32_Shdr)))
return EXIT_FAILURE;
if (!fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff + (elf->Ehdr->e_shstrndx * sizeof(Elf32_Shdr)), sizeof(Elf32_Shdr)))
return EXIT_FAILURE;
char *Sshstrtab = (char *)fetch(woody->file, woody->file_size, elf->Shdr[elf->Ehdr->e_shstrndx].sh_offset, 0);
if (Sshstrtab == NULL)
return EXIT_FAILURE;
for (int i = 0; i < elf->Ehdr->e_shnum;i++)
{
if (elf->Shdr[i].sh_type == SHT_PROGBITS && elf->Shdr[i].sh_flags & SHF_EXECINSTR && elf->Shdr[i].sh_flags & SHF_ALLOC && elf->Shdr[i].sh_flags & SHF_EXECINSTR)
{
if (Sshstrtab + elf->Shdr[i].sh_name < (char *)woody->file + woody->file_size && !ft_strncmp(".text\0", Sshstrtab + elf->Shdr[i].sh_name, 6))
{
elf->text_section = &elf->Shdr[i];
return EXIT_SUCCESS;
}
}
}
return EXIT_FAILURE;
}

View File

@ -1,101 +0,0 @@
#include "../includes/woody.h"
int get_load_segment64(t_elf_content *woody, int start, bool executable)
{
t_elf64 *elf = woody->elf64;
for (int i = start; i < elf->Ehdr->e_phnum; i++)
{
if (elf->Phdr[i].p_type == PT_LOAD)
{
if (executable)
{
if (elf->Phdr[i].p_flags & PF_X)
return i;
}
else
return i;
}
}
return -1;
}
int inject64(t_elf_content *woody)
{
t_elf64 *elf = woody->elf64;
t_payload *payload = get_payload();
if (!payload)
return EXIT_FAILURE;
int i = get_load_segment64(woody, 0, true);
int j = get_load_segment64(woody, i + 1, false);
if (i == -1 || j != i + 1)
{
free(payload->payload);
free(payload);
return ft_put_error("PT_LOAD segment missing");
}
size_t code_cave_size = elf->Phdr[j].p_offset - (elf->Phdr[i].p_offset + elf->Phdr[i].p_filesz);
size_t payload_position = elf->Phdr[i].p_offset + elf->Phdr[i].p_filesz;
if (code_cave_size < (size_t)payload->len)
{
free(payload->payload);
free(payload);
return ft_put_error("Unable to insert payload, not enough space for code cave");
}
encrypt(woody->file, elf->Phdr[i].p_offset, elf->Phdr[i].p_memsz);
if (insert_payload(woody, payload, payload_position, elf->Ehdr->e_entry, elf->Phdr[i].p_offset, elf->Phdr[i].p_memsz))
{
free(payload->payload);
free(payload);
return ft_put_error("Unable to insert payload, please regenerate it");
}
elf->Ehdr->e_entry = payload_position;
elf->Phdr[i].p_filesz += payload->len;
elf->Phdr[i].p_memsz += payload->len;
elf->Phdr[i].p_flags = PF_X | PF_W | PF_R;
free(payload->payload);
free(payload);
return EXIT_SUCCESS;
}
int get_elf_sections64(t_elf_content *woody)
{
t_elf64 *elf = woody->elf64;
elf->Ehdr = (Elf64_Ehdr *)fetch(woody->file, woody->file_size, 0, sizeof(Elf64_Ehdr));
if (!elf->Ehdr)
return EXIT_FAILURE;
elf->Phdr = (Elf64_Phdr *)fetch(woody->file, woody->file_size, elf->Ehdr->e_phoff, sizeof(Elf64_Phdr));
if (!elf->Phdr)
return EXIT_FAILURE;
elf->Shdr = (Elf64_Shdr *)fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff, sizeof(Elf64_Shdr));
if (!elf->Shdr || !fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff, elf->Ehdr->e_shnum * sizeof(Elf64_Shdr)))
return EXIT_FAILURE;
if (!fetch(woody->file, woody->file_size, elf->Ehdr->e_shoff + (elf->Ehdr->e_shstrndx * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr)))
return EXIT_FAILURE;
char *Sshstrtab = (char *)fetch(woody->file, woody->file_size, elf->Shdr[elf->Ehdr->e_shstrndx].sh_offset, 0);
if (Sshstrtab == NULL)
return EXIT_FAILURE;
for (int i = 0; i < elf->Ehdr->e_shnum;i++)
{
if (elf->Shdr[i].sh_type == SHT_PROGBITS && elf->Shdr[i].sh_flags & SHF_EXECINSTR && elf->Shdr[i].sh_flags & SHF_ALLOC && elf->Shdr[i].sh_flags & SHF_EXECINSTR)
{
if (Sshstrtab + elf->Shdr[i].sh_name < (char *)woody->file + woody->file_size && !ft_strncmp(".text\0", Sshstrtab + elf->Shdr[i].sh_name, 6))
{
elf->text_section = &elf->Shdr[i];
return EXIT_SUCCESS;
}
}
}
return EXIT_FAILURE;
}