KeeLoqを題材にして、WSL内でLinuxの共有ライブラリ(WindowsでいうところのDLL)を作って、Pythonから呼び出してみます。まったく需要がなさそうなこの題材。まぁメモですから!
keeloq.cはCで実装したものそのまんまです。mainも消さずにほったらかし。
libkeeloq.mapはエクスポートする関数の指定です。DLLでいうところのdefファイル的なやつ。
Makefileは相変わらず稚拙な感じ。リンカオプションの"--version-script,libkeeloq.map"がキモです。
keeloq.c
#include <stdio.h> #include <stdint.h> uint32_t keeloq_enc(uint32_t pr,uint64_t kr){ uint32_t nlf_table=0x3a5c742e; uint32_t nlf_arg; uint32_t nlf; uint32_t newz; uint32_t i; for(i=0;i<528;i++){ nlf_arg=((pr&0x80000000)>>(31-4)) |((pr&0x04000000)>>(26-3)) |((pr&0x00100000)>>(20-2)) |((pr&0x00000200)>>(9-1)) |((pr&0x00000002)>>(1-0)); nlf=((nlf_table>>nlf_arg)&0x00000001); newz=nlf^((pr&0x00010000)>>16)^(pr&0x00000001)^(uint32_t)(kr&0x0000000000000001); pr=(newz<<31)|(pr>>1); kr=((kr&0x0000000000000001)<<63)|(kr>>1); } return pr; } uint32_t keeloq_dec(uint32_t cr,uint64_t kr){ uint32_t nlf_table=0x3a5c742e; uint32_t nlf_arg; uint32_t nlf; uint32_t newz; uint32_t i; for(i=0;i<528;i++){ nlf_arg=((cr&0x40000000)>>(30-4)) |((cr&0x02000000)>>(25-3)) |((cr&0x00080000)>>(19-2)) |((cr&0x00000100)>>(8-1)) |((cr&0x00000001)>>(0-0)); nlf=((nlf_table>>nlf_arg)&0x00000001); newz=nlf^((cr&0x00008000)>>15)^((cr&0x80000000)>>31)^(uint32_t)((kr&0x0000000000008000)>>15); cr=(cr<<1)|(newz); kr=((kr&0x8000000000000000)>>63)|(kr<<1); } return cr; } int main(int argc,char** argv){ uint32_t pr=0xf741e2db; uint64_t kr=0x5cec6701b79fd949; uint32_t cr; int i; cr=keeloq_enc(pr,kr); printf("%08X\n",cr); pr=keeloq_dec(cr,kr); printf("%08X\n",pr); return 0; }
libkeeloq.map
{ global: keeloq_enc; keeloq_dec; local: *; };
Makefile
CC = gcc CFLAGS = -fPIC -O4 -Wall -I/usr/local/include LDFLAGS+=-Wl,--version-script,libkeeloq.map libkeeloq.so: keeloq.o $(CC) keeloq.o $(LDFLAGS) -o libkeeloq.so keeloq.o: keeloq.c $(CC) $(CFLAGS) keeloq.c -c -o keeloq.o clean: rm keeloq.o libkeeloq.so
make
ってすると、
libkeeloq.so
ができます。
で、これをPythonから使ってみる。
keeloq.py
import ctypes dll = ctypes.cdll.LoadLibrary("./libkeeloq.so") pr=ctypes.c_uint32(0xf741e2db) kr=ctypes.c_uint64(0x5cec6701b79fd949) ret=ctypes.c_uint32(0x00000000) ret.value=dll.keeloq_enc(pr,kr) print(hex(ret.value))
うまくいきましたー。
コメントをお書きください