├── .gitignore ├── article-support ├── absolute.c ├── inject_test.py ├── shellcode.py ├── simple-1.c ├── simple-2.c ├── simple-2.py ├── simple-3.c ├── simple-4.c └── simple-5.c ├── chess.c ├── compile.sh ├── dump-elf-bytes ├── .gitignore ├── LICENSE ├── README.md ├── Setup.hs ├── app │ └── Main.hs ├── dump-elf-bytes.cabal ├── src │ └── Lib.hs ├── stack.yaml └── test │ └── Spec.hs ├── loader.c ├── loader_apply_move.py ├── loader_best_move.py ├── mmap-test.c ├── mmap-test.py ├── shellcode_bytes.py ├── sql ├── create-apply-move.sql ├── create-best-move.sql ├── create-perft.sql └── create-simple.sql └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.out 3 | -------------------------------------------------------------------------------- /article-support/absolute.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void _start(); 4 | 5 | int main() 6 | { 7 | printf("%d\n", 0xFFFFFEC2); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /article-support/inject_test.py: -------------------------------------------------------------------------------- 1 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE, c_uint64, c_int, c_char, create_string_buffer) 2 | 3 | from shellcode_bytes import shellcode, offset 4 | #shellcode = b'\xb8\x2a\x00\x00\x00\xc3' 5 | #offset = 26 6 | 7 | def execute(): 8 | libc = CDLL('libc.so.6') 9 | 10 | src_ptr = c_char_p(shellcode) 11 | size = len(shellcode) 12 | 13 | code_ptr = libc.valloc(size) 14 | code_ptr = c_void_p(code_ptr) 15 | 16 | memmove(code_ptr, src_ptr, size) 17 | err = libc.mprotect(code_ptr, size, 0x7) 18 | if 0 != err: 19 | raise Exception("mprotect: " + str(code)) 20 | 21 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 22 | fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1" 23 | move = "a1b1" 24 | fen2 = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/1R2K2R b Kkq - 0 1" 25 | move2 = "a6b5" 26 | result_buf = create_string_buffer(300) 27 | SHELLCODE_T = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p) 28 | 29 | fptr = cast(main_ptr, SHELLCODE_T) 30 | fptr(fen, move, result_buf) 31 | #fptr(fen2, move2, result_buf) 32 | libc.free(code_ptr) 33 | return result_buf.raw 34 | 35 | print execute() 36 | -------------------------------------------------------------------------------- /article-support/shellcode.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | 3 | shellcode = b'\xb8\x2a\x00\x00\x00\xc3' 4 | 5 | libc = CDLL('libc.so.6') 6 | 7 | src_ptr = c_char_p(shellcode) 8 | size = len(shellcode) 9 | 10 | code_ptr = libc.valloc(size) 11 | code_ptr = c_void_p(code_ptr) 12 | 13 | memmove(code_ptr, src_ptr, size) 14 | err = libc.mprotect(code_ptr, size, 0x7) 15 | if 0 != err: 16 | raise Exception("mprotect: " + str(code)) 17 | 18 | fptr = cast(code_ptr, CFUNCTYPE(c_long, c_long)) 19 | libc.free(code_ptr) 20 | -------------------------------------------------------------------------------- /article-support/simple-1.c: -------------------------------------------------------------------------------- 1 | int x() { return 42; } 2 | -------------------------------------------------------------------------------- /article-support/simple-2.c: -------------------------------------------------------------------------------- 1 | // gcc -c -O simple-2.c 2 | 3 | int custom_main(int l); 4 | static int factorial(int x); 5 | 6 | int custom_main(int l) { 7 | int ret = 0; 8 | for (int i = 0; i < l; i++) { 9 | ret += factorial(i); 10 | } 11 | return ret; 12 | } 13 | // 1 + 1 + 2 + 6 + 24 = 33 14 | 15 | static int factorial(int x) { 16 | if (x == 0) { return 1; } 17 | return x * factorial(x-1); 18 | } 19 | -------------------------------------------------------------------------------- /article-support/simple-2.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | shellcode = b'\xb8\x01\x00\x00\x00\x85\xff\x74\x0f\x53\x89\xfb\x8d\x7f\xff\xe8\xec\xff\xff\xff\x0f\xaf\xc3\x5b\xf3\xc3\x41\x54\x55\x53\x85\xff\x7e\x20\x41\x89\xfc\xbb\x00\x00\x00\x00\xbd\x00\x00\x00\x00\x89\xdf\xe8\xca\xff\xff\xff\x01\xc5\x83\xc3\x01\x41\x39\xdc\x75\xef\xeb\x05\xbd\x00\x00\x00\x00\x89\xe8\x5b\x5d\x41\x5c\xc3' 3 | offset = 26 # Decimal conversion of 1a, the beginning of custom_main 4 | 5 | libc = CDLL('libc.so.6') 6 | 7 | def get_executable_buffer(shellcode): 8 | src_ptr = c_char_p(shellcode) 9 | size = len(shellcode) 10 | 11 | code_ptr = libc.valloc(size) 12 | code_ptr = c_void_p(code_ptr) 13 | 14 | memmove(code_ptr, src_ptr, size) 15 | err = libc.mprotect(code_ptr, size, 0x7) 16 | if 0 != err: 17 | raise Exception("mprotect: " + str(code)) 18 | return code_ptr, size 19 | 20 | def execute(): 21 | code_ptr, size = get_executable_buffer(shellcode) 22 | 23 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 24 | SHELLCODE_T = CFUNCTYPE(c_int, c_int) 25 | 26 | fptr = cast(main_ptr, SHELLCODE_T) 27 | result = fptr(5) 28 | libc.free(code_ptr) 29 | return result 30 | 31 | print execute() 32 | -------------------------------------------------------------------------------- /article-support/simple-3.c: -------------------------------------------------------------------------------- 1 | long y() { return 42; } 2 | void* custom_main() { return &y; } 3 | 4 | /* int y() { return 42; } */ 5 | /* typedef int (*shellcode_t)(); */ 6 | /* long main() { return ((shellcode_t)0x400000)(); } */ 7 | -------------------------------------------------------------------------------- /article-support/simple-4.c: -------------------------------------------------------------------------------- 1 | // gcc -Os simple-4.c -c -fno-jump-tables 2 | int prime(int n) { 3 | switch (n) { 4 | case 1: return 2; 5 | case 2: return 3; 6 | case 3: return 5; 7 | case 4: return 7; 8 | case 5: return 11; 9 | case 6: return 13; 10 | case 7: return 17; 11 | case 8: return 19; 12 | default: __builtin_trap(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /article-support/simple-5.c: -------------------------------------------------------------------------------- 1 | unsigned long count_bits(unsigned long x) { return __builtin_popcountl(x); } 2 | -------------------------------------------------------------------------------- /chess.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef DEBUG 4 | #define abort() __builtin_trap(); 5 | //#define abort() throw "derp"; 6 | #define private static 7 | #else 8 | #define private static 9 | #define abort() __builtin_trap(); 10 | #endif 11 | 12 | // bb is 'bitboard' 13 | typedef struct gamestate { 14 | uint64_t rooks_bb; 15 | uint64_t knights_bb; 16 | uint64_t bishops_bb; 17 | uint64_t queens_bb; 18 | uint64_t kings_bb; 19 | uint64_t pawns_bb; 20 | union { 21 | uint64_t current_player_bb; 22 | uint64_t current_piece_bb; // For iterators 23 | }; 24 | int en_passant_sq; 25 | union { 26 | uint64_t castle_flags; 27 | uint64_t promotion_piece; // For iterators 28 | }; 29 | bool is_white; 30 | } gamestate; 31 | 32 | struct move { 33 | int from; 34 | int to; 35 | }; 36 | 37 | typedef gamestate iterator; 38 | typedef int piece; 39 | typedef int position; 40 | 41 | const piece PIECE_EMPTY = 0; 42 | const piece PIECE_ROOK = 1; 43 | const piece PIECE_KNIGHT = 2; 44 | const piece PIECE_BISHOP = 3; 45 | const piece PIECE_QUEEN = 4; 46 | const piece PIECE_KING = 5; 47 | const piece PIECE_PAWN = 6; 48 | 49 | const int VALUE_PAWN = 100; 50 | const int VALUE_KNIGHT = 300; 51 | const int VALUE_BISHOP = 300; 52 | const int VALUE_ROOK = 500; 53 | const int VALUE_QUEEN = 900; 54 | const int VALUE_AVAILABLE_MOVE = 5; // Points for each move available 55 | const int VALUE_CHECKMATE = -1000000; 56 | const int VALUE_NEGAMAX_START = 0x80000000; 57 | const int VALUE_CENTER = 10; // Points for holding the center 58 | const int VALUE_ATTACK = 20; // Points for being able to attack enemy pieces. 59 | 60 | const int DIRECTION_EAST = 0; 61 | const int DIRECTION_WEST = 1; 62 | const int DIRECTION_NORTH = 2; 63 | const int DIRECTION_SOUTH = 3; 64 | const int DIRECTION_NORTHEAST = 4; 65 | const int DIRECTION_NORTHWEST = 5; 66 | const int DIRECTION_SOUTHEAST = 6; 67 | const int DIRECTION_SOUTHWEST = 7; 68 | 69 | // CASTLE FLAGS 70 | const int CASTLE_WHITE_KINGSIDE = 0x1; 71 | const int CASTLE_WHITE_QUEENSIDE = 0x2; 72 | const int CASTLE_BLACK_KINGSIDE = 0x4; 73 | const int CASTLE_BLACK_QUEENSIDE = 0x8; 74 | 75 | const int CASTLE_KINGSIDE_KPOS = 6; 76 | const int CASTLE_QUEENSIDE_KPOS = 2; 77 | const int CASTLE_KINGSIDE_RPOS = 5; 78 | const int CASTLE_QUEENSIDE_RPOS = 3; 79 | 80 | const int NUM_BOARD_SQUARES = 8*8; 81 | 82 | const int RANK = 8; 83 | 84 | const int POSITION_INVALID = 255; 85 | 86 | const uint64_t RAY_A1A8 = 0x0101010101010101; 87 | const uint64_t RAY_H1H8 = RAY_A1A8 << (RANK-1); 88 | 89 | // Private functions 90 | 91 | private uint64_t bit(uint64_t idx) { 92 | if (idx >= 64 || idx < 0) { 93 | return 0; 94 | } 95 | return ((uint64_t)(1) << idx); 96 | } 97 | private uint64_t clear_bit(uint64_t x, uint64_t idx) { return x & ~bit(idx); } 98 | private bool is_bit_set(uint64_t x, uint64_t idx) { 99 | if (idx >= 64) { return false; } 100 | return x & bit(idx); 101 | } 102 | private uint64_t set_bit(uint64_t x, uint64_t idx) { return x | bit(idx); } 103 | private uint64_t lsb_first_set(uint64_t x) { return __builtin_ctzll(x); } 104 | private uint64_t msb_first_set(uint64_t x) { return (63 - __builtin_clzll(x)); } 105 | 106 | private int rank(int x) { return x / 8; } 107 | private int file(int x) { return x % 8; } 108 | private uint64_t offset(uint64_t x, int os) 109 | { 110 | #ifdef DEBUG 111 | if (os >= 64 || os <= -64) { 112 | throw "???"; 113 | } 114 | #endif 115 | if (os < 0) { 116 | return (x >> -os); 117 | } else { 118 | return (x << os); 119 | } 120 | } 121 | 122 | private gamestate zerostate() 123 | { 124 | gamestate x; 125 | x.current_piece_bb = 0; 126 | x.rooks_bb = 0; 127 | x.knights_bb = 0; 128 | x.bishops_bb = 0; 129 | x.queens_bb = 0; 130 | x.kings_bb = 0; 131 | x.pawns_bb = 0; 132 | x.en_passant_sq = POSITION_INVALID; 133 | x.castle_flags = 0; 134 | x.is_white = true; 135 | return x; 136 | } 137 | 138 | 139 | private uint64_t mkPosition(int file, int rank) 140 | { 141 | return rank * RANK + file; 142 | } 143 | 144 | const uint64_t RAY_A1H8 = 145 | bit(mkPosition(0,0)) | 146 | bit(mkPosition(1,1)) | 147 | bit(mkPosition(2,2)) | 148 | bit(mkPosition(3,3)) | 149 | bit(mkPosition(4,4)) | 150 | bit(mkPosition(5,5)) | 151 | bit(mkPosition(6,6)) | 152 | bit(mkPosition(7,7)) 153 | ; 154 | 155 | #ifdef PRINT 156 | #include 157 | private void print_bitboard(uint64_t bb) 158 | { 159 | for (int r = 8; r --> 0;) { 160 | for (int f = 0; f < 8; f++) { 161 | char c = is_bit_set(bb, mkPosition(f, r)) ? '1' : '0'; 162 | putchar(c); 163 | } 164 | putchar('\n'); 165 | } 166 | } 167 | #endif 168 | 169 | // https://chessprogramming.wikispaces.com/On+an+empty+Board#RayAttacks 170 | private uint64_t diagonal_mask(int center) 171 | { 172 | const uint64_t maindia = 0x8040201008040201; 173 | int diag =8*(center & 7) - (center & 56); 174 | int nort = -diag & ( diag >> 31); 175 | int sout = diag & (-diag >> 31); 176 | return (maindia >> sout) << nort; 177 | } 178 | 179 | private uint64_t antidiagonal_mask(int center) 180 | { 181 | const uint64_t maindia = 0x0102040810204080; 182 | int diag =56- 8*(center&7) - (center&56); 183 | int nort = -diag & ( diag >> 31); 184 | int sout = diag & (-diag >> 31); 185 | return (maindia >> sout) << nort; 186 | } 187 | 188 | // https://chessprogramming.wikispaces.com/Flipping+Mirroring+and+Rotating 189 | // See 'flipDiagA1H8' 190 | private uint64_t flipDiagA1H8(uint64_t x) 191 | { 192 | uint64_t t; 193 | const uint64_t k1 = 0x5500550055005500; 194 | const uint64_t k2 = 0x3333000033330000; 195 | const uint64_t k4 = 0x0f0f0f0f00000000; 196 | t = k4 & (x ^ (x << 28)); 197 | x ^= t ^ (t >> 28) ; 198 | t = k2 & (x ^ (x << 14)); 199 | x ^= t ^ (t >> 14) ; 200 | t = k1 & (x ^ (x << 7)); 201 | x ^= t ^ (t >> 7) ; 202 | return x; 203 | } 204 | 205 | private uint64_t mirror_horizontal (uint64_t x) { 206 | const uint64_t k1 = 0x5555555555555555; 207 | const uint64_t k2 = 0x3333333333333333; 208 | const uint64_t k4 = 0x0f0f0f0f0f0f0f0f; 209 | x = ((x >> 1) & k1) + 2*(x & k1); 210 | x = ((x >> 2) & k2) + 4*(x & k2); 211 | x = ((x >> 4) & k4) + 16*(x & k4); 212 | return x; 213 | } 214 | 215 | private uint64_t flip_vertical(uint64_t x) 216 | { 217 | return 218 | ( (x << 56) ) | 219 | ( (x << 40) & (0x00ff000000000000) ) | 220 | ( (x << 24) & (0x0000ff0000000000) ) | 221 | ( (x << 8) & (0x000000ff00000000) ) | 222 | ( (x >> 8) & (0x00000000ff000000) ) | 223 | ( (x >> 24) & (0x0000000000ff0000) ) | 224 | ( (x >> 40) & (0x000000000000ff00) ) | 225 | ( (x >> 56) ); 226 | } 227 | 228 | // We use a monochrome board, so white is always the one to move, and we flip the board after each move. 229 | private uint64_t flip_bb(uint64_t x) 230 | { 231 | return __builtin_bswap64(x); 232 | //return mirror_horizontal(__builtin_bswap64(x)); 233 | } 234 | 235 | private uint64_t rotate_bb(uint64_t x) 236 | { 237 | return flip_vertical(flipDiagA1H8(x)); 238 | } 239 | 240 | const uint64_t RAY_A8H1 = rotate_bb(RAY_A1H8); 241 | 242 | private uint64_t get_piece_bb(gamestate x, int piece) 243 | { 244 | switch (piece) { 245 | case PIECE_ROOK: 246 | return x.rooks_bb; 247 | case PIECE_KNIGHT: 248 | return x.knights_bb; 249 | case PIECE_BISHOP: 250 | return x.bishops_bb; 251 | case PIECE_QUEEN: 252 | return x.queens_bb; 253 | case PIECE_KING: 254 | return x.kings_bb; 255 | case PIECE_PAWN: 256 | return x.pawns_bb; 257 | } 258 | abort(); 259 | } 260 | 261 | private gamestate set_piece_bb(gamestate x, int piece, uint64_t bb) 262 | { 263 | switch (piece) { 264 | case PIECE_ROOK: 265 | x.rooks_bb = bb; 266 | return x; 267 | case PIECE_KNIGHT: 268 | x.knights_bb = bb; 269 | return x; 270 | case PIECE_BISHOP: 271 | x.bishops_bb = bb; 272 | return x; 273 | case PIECE_QUEEN: 274 | x.queens_bb = bb; 275 | return x; 276 | case PIECE_KING: 277 | x.kings_bb = bb; 278 | return x; 279 | case PIECE_PAWN: 280 | x.pawns_bb = bb; 281 | return x; 282 | default: 283 | abort(); 284 | } 285 | } 286 | 287 | private int next_iterator_piece(iterator x) 288 | { 289 | if (x.rooks_bb) 290 | return PIECE_ROOK; 291 | if (x.knights_bb) 292 | return PIECE_KNIGHT; 293 | if (x.bishops_bb) 294 | return PIECE_BISHOP; 295 | if (x.queens_bb) 296 | return PIECE_QUEEN; 297 | if (x.kings_bb) 298 | return PIECE_KING; 299 | if (x.pawns_bb) 300 | return PIECE_PAWN; 301 | return PIECE_EMPTY; 302 | } 303 | 304 | private int iterator_position(iterator x) 305 | { 306 | int piece = next_iterator_piece(x); 307 | if (piece == PIECE_EMPTY) { 308 | return POSITION_INVALID; 309 | } 310 | uint64_t piece_bb = get_piece_bb(x, piece); 311 | int idx = lsb_first_set(piece_bb); 312 | return idx; 313 | } 314 | 315 | private int promotion_piece(move m) 316 | { 317 | return (m.to >> 6); 318 | } 319 | 320 | private move dereference_iterator(iterator i) 321 | { 322 | move m; 323 | m.from = iterator_position(i); 324 | m.to = lsb_first_set(i.current_piece_bb); 325 | m.to |= (i.promotion_piece << 6); 326 | return m; 327 | } 328 | 329 | private uint64_t advance_bb_iterator(uint64_t x) 330 | { 331 | return x & (x-1); 332 | } 333 | 334 | private bool is_iterator_finished(iterator x) 335 | { 336 | return 337 | ! x.rooks_bb && 338 | ! x.knights_bb && 339 | ! x.bishops_bb && 340 | ! x.queens_bb && 341 | ! x.kings_bb && 342 | ! x.pawns_bb && 343 | ! x.current_piece_bb 344 | ; 345 | } 346 | 347 | // When a piece is moving west, it may wrap around to be east. 348 | // So we mask out the eastmost column, since it's impossible anyways. 349 | private uint64_t guard_west(uint64_t x) { 350 | return x & ~RAY_H1H8; 351 | } 352 | 353 | private uint64_t guard_east(uint64_t x) { 354 | return x & ~RAY_A1A8; 355 | } 356 | 357 | private int move_direction(int idx, int direction) 358 | { 359 | if (idx < 0 || idx >= 64) { 360 | return POSITION_INVALID; 361 | } 362 | switch (direction) { 363 | case DIRECTION_EAST: 364 | if (idx % 8 == 7) 365 | return POSITION_INVALID; 366 | return idx + 1; 367 | case DIRECTION_WEST: 368 | if (idx % 8 == 0) 369 | return POSITION_INVALID; 370 | return idx - 1; 371 | case DIRECTION_NORTH: 372 | return idx + RANK; 373 | case DIRECTION_SOUTH: 374 | return idx - RANK; 375 | case DIRECTION_NORTHEAST: 376 | if (file(idx) == 7) { 377 | return POSITION_INVALID; 378 | } 379 | return (idx + RANK + 1); 380 | case DIRECTION_NORTHWEST: 381 | if (file(idx) == 0) { 382 | return POSITION_INVALID; 383 | } 384 | return (idx + RANK - 1); 385 | case DIRECTION_SOUTHEAST: 386 | if (file(idx) == 7) { 387 | return POSITION_INVALID; 388 | } 389 | return (idx - RANK + 1); 390 | case DIRECTION_SOUTHWEST: 391 | if (file(idx) == 0) { 392 | return POSITION_INVALID; 393 | } 394 | return (idx - RANK - 1); 395 | default: 396 | abort(); 397 | } 398 | } 399 | 400 | private uint64_t all_pieces(gamestate x) 401 | { 402 | return 403 | x.rooks_bb | 404 | x.knights_bb | 405 | x.bishops_bb | 406 | x.queens_bb | 407 | x.kings_bb | 408 | x.pawns_bb 409 | ; 410 | } 411 | 412 | private uint64_t enemy_pieces(gamestate x) 413 | { 414 | return all_pieces(x) ^ x.current_player_bb; 415 | } 416 | 417 | private uint64_t valid_pawn_moves(gamestate x, int center) 418 | { 419 | uint64_t moves_bb = 0; 420 | // Non-captures 421 | if (! is_bit_set(all_pieces(x), center + RANK)) { 422 | uint64_t noncaptures_bb = bit(center + RANK); 423 | uint64_t pcs = all_pieces(x); 424 | if (rank(center) == 1 && ! is_bit_set(pcs, center + RANK) && ! is_bit_set(pcs, center + RANK*2)) { 425 | noncaptures_bb |= bit(center + RANK + RANK); 426 | } 427 | moves_bb |= noncaptures_bb; 428 | } 429 | // Captures 430 | { 431 | uint64_t captures_bb = 0; 432 | if (file(center) > 0) { 433 | captures_bb |= bit(move_direction(center + RANK, DIRECTION_WEST)); 434 | } 435 | if (file(center) < 7) { 436 | captures_bb |= bit(move_direction(center + RANK, DIRECTION_EAST)); 437 | } 438 | captures_bb &= all_pieces(x) ^ x.current_player_bb; 439 | if ((file(center) < 7 && x.en_passant_sq == center + RANK + 1) || 440 | (file(center) > 0 && x.en_passant_sq == center + RANK - 1)) { 441 | captures_bb |= bit(x.en_passant_sq); 442 | } 443 | moves_bb |= captures_bb; 444 | } 445 | return moves_bb; 446 | } 447 | 448 | private uint64_t valid_knight_moves(gamestate x, int idx) 449 | { 450 | uint64_t moves_bb = 0; 451 | moves_bb |= guard_west(bit(move_direction(idx + 2 * RANK, DIRECTION_WEST))); 452 | moves_bb |= guard_east(bit(move_direction(idx + 2 * RANK, DIRECTION_EAST))); 453 | 454 | moves_bb |= guard_west(bit(move_direction(idx - 2 * RANK, DIRECTION_WEST))); 455 | moves_bb |= guard_east(bit(move_direction(idx - 2 * RANK, DIRECTION_EAST))); 456 | 457 | moves_bb |= bit(move_direction(move_direction(move_direction(idx, DIRECTION_EAST), DIRECTION_EAST), DIRECTION_NORTH)); 458 | moves_bb |= bit(move_direction(move_direction(move_direction(idx, DIRECTION_EAST), DIRECTION_EAST), DIRECTION_SOUTH)); 459 | 460 | moves_bb |= bit(move_direction(move_direction(move_direction(idx, DIRECTION_WEST), DIRECTION_WEST), DIRECTION_NORTH)); 461 | moves_bb |= bit(move_direction(move_direction(move_direction(idx, DIRECTION_WEST), DIRECTION_WEST), DIRECTION_SOUTH)); 462 | 463 | moves_bb &= ~x.current_player_bb; 464 | return moves_bb; 465 | } 466 | 467 | private uint64_t bitrange(int start, int end) 468 | { 469 | uint64_t end_bb = bit(end+1)-1; 470 | uint64_t start_bb = bit(start)-1; 471 | return end_bb ^ start_bb; 472 | } 473 | 474 | private uint64_t mkRay(int center, int direction) 475 | { 476 | int rOs, fOs; 477 | switch (direction) { 478 | case DIRECTION_NORTHWEST: rOs = 1; fOs = -1; break; 479 | case DIRECTION_NORTH: rOs = 1; fOs = 0; break; 480 | case DIRECTION_NORTHEAST: rOs = 1; fOs = 1; break; 481 | case DIRECTION_EAST: rOs = 0; fOs = 1; break; 482 | case DIRECTION_SOUTHEAST: rOs = -1; fOs = 1; break; 483 | case DIRECTION_SOUTH: rOs = -1; fOs = 0; break; 484 | case DIRECTION_SOUTHWEST: rOs = -1; fOs = -1; break; 485 | case DIRECTION_WEST: rOs = 0; fOs = -1; break; 486 | default: abort(); 487 | } 488 | uint64_t ray; 489 | uint64_t next = bit(center); 490 | do { 491 | ray = next; 492 | next = offset(next, RANK * rOs); 493 | next = offset(next, fOs); 494 | switch (fOs) { 495 | case 1: next &= ~RAY_A1A8; break; 496 | case -1: next &= ~RAY_H1H8; break; 497 | default: break; 498 | } 499 | next |= ray; 500 | } while (ray != next); 501 | ray = clear_bit(ray, center); 502 | return ray; 503 | } 504 | 505 | private int closest_blocker(uint64_t blockers_ray, int direction) 506 | { 507 | if (blockers_ray == 0) 508 | return POSITION_INVALID; 509 | switch (direction) { 510 | case DIRECTION_NORTHWEST: 511 | case DIRECTION_NORTH: 512 | case DIRECTION_NORTHEAST: 513 | case DIRECTION_EAST: 514 | return lsb_first_set(blockers_ray); 515 | case DIRECTION_SOUTHEAST: 516 | case DIRECTION_SOUTH: 517 | case DIRECTION_SOUTHWEST: 518 | case DIRECTION_WEST: 519 | return msb_first_set(blockers_ray); 520 | default: 521 | abort(); 522 | } 523 | } 524 | 525 | private uint64_t shoot_ray_until_blocker(gamestate state, int idx, int direction) 526 | { 527 | uint64_t pieces = all_pieces(state); 528 | uint64_t base_ray = mkRay(idx, direction); 529 | uint64_t blockers = base_ray & pieces; 530 | int blocker = closest_blocker(blockers, direction); 531 | if (blocker == POSITION_INVALID) { 532 | return base_ray; 533 | } else { 534 | uint64_t blocker_ray = mkRay(blocker, direction); 535 | uint64_t movable_squares_without_capture = base_ray ^ blocker_ray; 536 | bool allow_capture = ! is_bit_set(state.current_player_bb, blocker); 537 | if (allow_capture) 538 | return movable_squares_without_capture | bit(blocker); 539 | else 540 | return movable_squares_without_capture & ~bit(blocker); 541 | } 542 | } 543 | 544 | private uint64_t valid_bishop_moves(gamestate x, int idx) 545 | { 546 | return 547 | shoot_ray_until_blocker(x, idx, DIRECTION_NORTHEAST) | 548 | shoot_ray_until_blocker(x, idx, DIRECTION_NORTHWEST) | 549 | shoot_ray_until_blocker(x, idx, DIRECTION_SOUTHEAST) | 550 | shoot_ray_until_blocker(x, idx, DIRECTION_SOUTHWEST) 551 | ; 552 | } 553 | 554 | private uint64_t valid_rook_moves(gamestate x, int idx) 555 | { 556 | return 557 | shoot_ray_until_blocker(x, idx, DIRECTION_NORTH) | 558 | shoot_ray_until_blocker(x, idx, DIRECTION_WEST) | 559 | shoot_ray_until_blocker(x, idx, DIRECTION_EAST) | 560 | shoot_ray_until_blocker(x, idx, DIRECTION_SOUTH) 561 | ; 562 | } 563 | 564 | private uint64_t valid_king_moves(gamestate g, int idx) 565 | { 566 | uint64_t ret = 567 | bit(move_direction(idx, DIRECTION_EAST)) | 568 | bit(move_direction(idx, DIRECTION_WEST)) | 569 | bit(move_direction(idx, DIRECTION_NORTH)) | 570 | bit(move_direction(idx, DIRECTION_SOUTH)) | 571 | bit(move_direction(idx, DIRECTION_NORTHEAST)) | 572 | bit(move_direction(idx, DIRECTION_SOUTHEAST)) | 573 | bit(move_direction(idx, DIRECTION_NORTHWEST)) | 574 | bit(move_direction(idx, DIRECTION_SOUTHWEST)) 575 | ; 576 | if ((g.castle_flags & CASTLE_WHITE_KINGSIDE)) { 577 | uint64_t pcs = all_pieces(g); 578 | if (is_bit_set(pcs, CASTLE_KINGSIDE_KPOS) || 579 | is_bit_set(pcs, CASTLE_KINGSIDE_RPOS)) { 580 | goto skip_kingside; 581 | } 582 | ret |= bit(CASTLE_KINGSIDE_KPOS); 583 | } 584 | skip_kingside: 585 | if ((g.castle_flags & CASTLE_WHITE_QUEENSIDE)) { 586 | uint64_t pcs = all_pieces(g); 587 | if (is_bit_set(pcs, CASTLE_QUEENSIDE_RPOS) || 588 | is_bit_set(pcs, CASTLE_QUEENSIDE_KPOS) || 589 | is_bit_set(pcs, CASTLE_QUEENSIDE_KPOS-1)) { 590 | goto skip_queenside; 591 | } 592 | ret |= bit(CASTLE_QUEENSIDE_KPOS); 593 | } 594 | skip_queenside: 595 | ret &= ~ g.current_piece_bb; 596 | return ret; 597 | } 598 | 599 | private uint64_t valid_queen_moves(gamestate x, int idx) 600 | { 601 | return 602 | valid_bishop_moves(x, idx) | 603 | valid_rook_moves(x, idx) 604 | ; 605 | } 606 | 607 | private int get_piece(gamestate x, int idx) 608 | { 609 | if (is_bit_set(x.rooks_bb, idx)) 610 | return PIECE_ROOK; 611 | if (is_bit_set(x.knights_bb, idx)) 612 | return PIECE_KNIGHT; 613 | if (is_bit_set(x.bishops_bb, idx)) 614 | return PIECE_BISHOP; 615 | if (is_bit_set(x.queens_bb, idx)) 616 | return PIECE_QUEEN; 617 | if (is_bit_set(x.kings_bb, idx)) 618 | return PIECE_KING; 619 | if (is_bit_set(x.pawns_bb, idx)) 620 | return PIECE_PAWN; 621 | return PIECE_EMPTY; 622 | } 623 | 624 | private uint64_t valid_piece_moves(gamestate x, int idx) 625 | { 626 | int piece = get_piece(x, idx); 627 | switch (piece) { 628 | case PIECE_ROOK: 629 | return valid_rook_moves(x, idx); 630 | case PIECE_KNIGHT: 631 | return valid_knight_moves(x, idx); 632 | case PIECE_BISHOP: 633 | return valid_bishop_moves(x, idx); 634 | case PIECE_QUEEN: 635 | return valid_queen_moves(x, idx); 636 | case PIECE_KING: 637 | return valid_king_moves(x, idx); 638 | case PIECE_PAWN: 639 | return valid_pawn_moves(x, idx); 640 | default: 641 | abort(); 642 | } 643 | } 644 | 645 | private iterator reset_iterator_promotion_piece(gamestate g, iterator i) 646 | { 647 | if (is_iterator_finished(i)) { 648 | return i; 649 | } 650 | int idx = iterator_position(i); 651 | int piece = get_piece(g, idx); 652 | if (piece == PIECE_PAWN && 653 | rank(idx) == 6 && 654 | i.current_piece_bb != 0) { 655 | i.promotion_piece = PIECE_QUEEN; 656 | } 657 | return i; 658 | } 659 | 660 | private iterator reset_iterator_moves(gamestate g, iterator i) 661 | { 662 | if (is_iterator_finished(i)) { 663 | return zerostate(); 664 | } else { 665 | int idx = iterator_position(i); 666 | uint64_t moves = valid_piece_moves(g, idx); 667 | i.current_piece_bb = moves; 668 | i = reset_iterator_promotion_piece(g, i); 669 | return i; 670 | } 671 | } 672 | 673 | private iterator advance_iterator(gamestate g, iterator i) 674 | { 675 | if (i.current_piece_bb) { 676 | if (i.promotion_piece) { 677 | i.promotion_piece--; 678 | } 679 | if (!i.promotion_piece) { 680 | i.current_piece_bb = advance_bb_iterator(i.current_piece_bb); 681 | i = reset_iterator_promotion_piece(g, i); 682 | } 683 | } 684 | 685 | while (! is_iterator_finished(i) && ! i.current_piece_bb) { 686 | if (i.rooks_bb) { 687 | i.rooks_bb = advance_bb_iterator(i.rooks_bb); 688 | } else if (i.knights_bb) { 689 | i.knights_bb = advance_bb_iterator(i.knights_bb); 690 | } else if (i.bishops_bb) { 691 | i.bishops_bb = advance_bb_iterator(i.bishops_bb); 692 | } else if (i.queens_bb) { 693 | i.queens_bb = advance_bb_iterator(i.queens_bb); 694 | } else if (i.kings_bb) { 695 | i.kings_bb = advance_bb_iterator(i.kings_bb); 696 | } else if (i.pawns_bb) { 697 | i.pawns_bb = advance_bb_iterator(i.pawns_bb); 698 | } 699 | i = reset_iterator_moves(g, i); 700 | } 701 | if (is_iterator_finished(i) && i.current_piece_bb != 0) { 702 | abort(); 703 | } 704 | 705 | return i; 706 | } 707 | 708 | private gamestate switch_sides(gamestate x) 709 | { 710 | uint64_t enemy_pieces_bb = enemy_pieces(x); 711 | x.current_player_bb = enemy_pieces_bb; 712 | 713 | x.rooks_bb = __builtin_bswap64(x.rooks_bb); 714 | x.knights_bb = __builtin_bswap64(x.knights_bb); 715 | x.bishops_bb = __builtin_bswap64(x.bishops_bb); 716 | x.queens_bb = __builtin_bswap64(x.queens_bb); 717 | x.kings_bb = __builtin_bswap64(x.kings_bb); 718 | x.pawns_bb = __builtin_bswap64(x.pawns_bb); 719 | return x; 720 | } 721 | 722 | private iterator mkIterator(gamestate g) 723 | { 724 | iterator x = g; 725 | x.rooks_bb &= x.current_player_bb; 726 | x.knights_bb &= x.current_player_bb; 727 | x.bishops_bb &= x.current_player_bb; 728 | x.queens_bb &= x.current_player_bb; 729 | x.kings_bb &= x.current_player_bb; 730 | x.pawns_bb &= x.current_player_bb; 731 | x.promotion_piece = 0; 732 | 733 | x = reset_iterator_moves(g, x); 734 | if (! x.current_piece_bb) { 735 | x = advance_iterator(g, x); 736 | } 737 | 738 | return x; 739 | } 740 | 741 | private uint64_t all_rotations(uint64_t bb) 742 | { 743 | bb |= rotate_bb(bb); 744 | bb |= rotate_bb(bb); 745 | bb |= rotate_bb(bb); 746 | return bb; 747 | } 748 | 749 | private gamestate new_game() 750 | { 751 | gamestate x; 752 | x.rooks_bb = 753 | bit(mkPosition(0,0)) | 754 | bit(mkPosition(7,0)) | 755 | bit(mkPosition(0,7)) | 756 | bit(mkPosition(7,7)); 757 | x.knights_bb = 758 | bit(mkPosition(1,0)) | 759 | bit(mkPosition(6,0)) | 760 | bit(mkPosition(1,7)) | 761 | bit(mkPosition(6,7)); 762 | x.bishops_bb = 763 | bit(mkPosition(2,0)) | 764 | bit(mkPosition(5,0)) | 765 | bit(mkPosition(2,7)) | 766 | bit(mkPosition(5,7)); 767 | x.queens_bb = 768 | bit(mkPosition(3,0)) | 769 | bit(mkPosition(3,7)); 770 | x.kings_bb = 771 | bit(mkPosition(4,0)) | 772 | bit(mkPosition(4,7)); 773 | x.pawns_bb = 774 | ((uint64_t)0xFF << RANK) | 775 | ((uint64_t)0xFF << (6*RANK)); 776 | x.current_player_bb = 0xFFFF; 777 | x.en_passant_sq = POSITION_INVALID; 778 | x.castle_flags = 0xF; 779 | x.is_white = true; 780 | return x; 781 | } 782 | 783 | // Flips the board so white is black and black is white. 784 | // In our model, it is always white's turn to move. 785 | private gamestate swap_board(gamestate g) 786 | { 787 | g.current_player_bb ^= all_pieces(g); 788 | g.rooks_bb = flip_bb(g.rooks_bb); 789 | g.knights_bb = flip_bb(g.knights_bb); 790 | g.bishops_bb = flip_bb(g.bishops_bb); 791 | g.queens_bb = flip_bb(g.queens_bb); 792 | g.kings_bb = flip_bb(g.kings_bb); 793 | g.pawns_bb = flip_bb(g.pawns_bb); 794 | g.current_player_bb = flip_bb(g.current_player_bb); 795 | if (g.en_passant_sq != POSITION_INVALID) { 796 | g.en_passant_sq = mkPosition(file(g.en_passant_sq), 7 - rank(g.en_passant_sq)); 797 | } 798 | { 799 | int flags = 0; 800 | if (g.castle_flags & CASTLE_WHITE_KINGSIDE) 801 | flags |= CASTLE_BLACK_KINGSIDE; 802 | if (g.castle_flags & CASTLE_WHITE_QUEENSIDE) 803 | flags |= CASTLE_BLACK_QUEENSIDE; 804 | if (g.castle_flags & CASTLE_BLACK_KINGSIDE) 805 | flags |= CASTLE_WHITE_KINGSIDE; 806 | if (g.castle_flags & CASTLE_BLACK_QUEENSIDE) 807 | flags |= CASTLE_WHITE_QUEENSIDE; 808 | g.castle_flags = flags; 809 | } 810 | return g; 811 | } 812 | 813 | private move swap_move(move m) 814 | { 815 | m.from = mkPosition(file(m.from), 7 - rank(m.from)); 816 | m.to = mkPosition(file(m.to), 7 - rank(m.to)); 817 | return m; 818 | } 819 | 820 | private bool is_kingside_castle(gamestate g, move m) 821 | { 822 | int from_piece = get_piece(g, m.from); 823 | return 824 | from_piece == PIECE_KING && 825 | m.to == CASTLE_KINGSIDE_KPOS && 826 | (g.castle_flags & CASTLE_WHITE_KINGSIDE); 827 | } 828 | 829 | private bool is_queenside_castle(gamestate g, move m) 830 | { 831 | int from_piece = get_piece(g, m.from); 832 | return 833 | from_piece == PIECE_KING && 834 | m.to == CASTLE_QUEENSIDE_KPOS && 835 | (g.castle_flags & CASTLE_WHITE_QUEENSIDE); 836 | } 837 | 838 | private bool is_promotion(move m) { return promotion_piece(m) == PIECE_EMPTY; } 839 | 840 | private gamestate apply_move(gamestate g, move m) 841 | { 842 | gamestate g_orig = g; 843 | int from_piece = get_piece(g, m.from); 844 | int prom_piece = promotion_piece(m); 845 | m.to &= 0x3F; 846 | int to_piece = get_piece(g, m.to); 847 | if (to_piece != PIECE_EMPTY) { 848 | uint64_t to_bb = get_piece_bb(g, to_piece); 849 | g = set_piece_bb(g, to_piece, clear_bit(to_bb, m.to)); 850 | } 851 | // Non-promotion moves 852 | if (prom_piece == PIECE_EMPTY) { 853 | uint64_t from_bb = get_piece_bb(g, from_piece); 854 | g = set_piece_bb(g, from_piece, clear_bit(from_bb, m.from) | bit(m.to)); 855 | // Promotions 856 | } else { 857 | uint64_t piece_bb = get_piece_bb(g, prom_piece); 858 | g.pawns_bb = clear_bit(g.pawns_bb, m.from); 859 | g = set_piece_bb(g, prom_piece, piece_bb | bit(m.to)); 860 | } 861 | // Capture the pawn properly during En Passant capture 862 | if (from_piece == PIECE_PAWN && m.to == g.en_passant_sq) { 863 | g.pawns_bb = clear_bit(g.pawns_bb, g.en_passant_sq - RANK); 864 | } 865 | // Set En Passant target square on double-jump 866 | if (from_piece == PIECE_PAWN && rank(m.to) - rank(m.from) == 2) { 867 | g.en_passant_sq = m.from + RANK; 868 | } else { 869 | g.en_passant_sq = POSITION_INVALID; 870 | } 871 | // Check for kingside castle. 872 | if (is_kingside_castle(g_orig, m)) { 873 | g.castle_flags &= ~CASTLE_WHITE_KINGSIDE; 874 | g.rooks_bb = clear_bit(g.rooks_bb, mkPosition(7,0)); 875 | g.current_piece_bb = clear_bit(g.current_piece_bb, mkPosition(7,0)); 876 | g.rooks_bb = set_bit(g.rooks_bb, CASTLE_KINGSIDE_RPOS); 877 | g.current_piece_bb = set_bit(g.current_piece_bb, CASTLE_KINGSIDE_RPOS); 878 | } 879 | // Check for queenside castle 880 | if (is_queenside_castle(g_orig,m)) { 881 | g.castle_flags &= ~CASTLE_WHITE_QUEENSIDE; 882 | g.rooks_bb = clear_bit(g.rooks_bb, mkPosition(0,0)); 883 | g.current_piece_bb = clear_bit(g.current_piece_bb, mkPosition(0,0)); 884 | g.rooks_bb = set_bit(g.rooks_bb, CASTLE_QUEENSIDE_RPOS); 885 | g.current_piece_bb = set_bit(g.current_piece_bb, CASTLE_QUEENSIDE_RPOS); 886 | } 887 | // Clear kingside rook flags 888 | if (g.castle_flags & CASTLE_WHITE_KINGSIDE && 889 | from_piece == PIECE_ROOK && 890 | m.from == mkPosition(7,0)) { 891 | g.castle_flags &= ~CASTLE_WHITE_KINGSIDE; 892 | } 893 | // Clear queenside rook flags 894 | if (g.castle_flags & CASTLE_WHITE_QUEENSIDE && 895 | from_piece == PIECE_ROOK && 896 | m.from == mkPosition(0,0)) { 897 | g.castle_flags &= ~CASTLE_WHITE_QUEENSIDE; 898 | } 899 | // Clear eaten kingside rook flags 900 | if (to_piece == PIECE_ROOK && 901 | m.to == mkPosition(7,7)) { 902 | g.castle_flags &= ~CASTLE_BLACK_KINGSIDE; 903 | } 904 | // Clear eaten queenside rook flags 905 | if (to_piece == PIECE_ROOK && 906 | m.to == mkPosition(0,7)) { 907 | g.castle_flags &= ~CASTLE_BLACK_QUEENSIDE; 908 | } 909 | // Clear king's castling flags 910 | if (from_piece == PIECE_KING) { 911 | g.castle_flags &= ~(CASTLE_WHITE_KINGSIDE | CASTLE_WHITE_QUEENSIDE); 912 | } 913 | // Set colors 914 | g.current_player_bb = clear_bit(g.current_player_bb, m.from) | bit(m.to); 915 | 916 | g.is_white = ! g.is_white; 917 | 918 | g = swap_board(g); 919 | 920 | return g; 921 | } 922 | 923 | private uint64_t mkRank(int idx) { return ((uint64_t)0xFF << (idx*RANK)); } 924 | private uint64_t mkFile(int idx) { 925 | return 926 | bit(mkPosition(idx,0)) | 927 | bit(mkPosition(idx,1)) | 928 | bit(mkPosition(idx,2)) | 929 | bit(mkPosition(idx,3)) | 930 | bit(mkPosition(idx,4)) | 931 | bit(mkPosition(idx,5)) | 932 | bit(mkPosition(idx,6)) | 933 | bit(mkPosition(idx,7)); 934 | } 935 | 936 | private bool iter_lt(iterator x, iterator y) 937 | { 938 | return 939 | (x.rooks_bb < y.rooks_bb || 940 | (x.rooks_bb == y.rooks_bb && 941 | (x.knights_bb < y.knights_bb || 942 | (x.knights_bb == y.knights_bb && 943 | (x.bishops_bb < y.bishops_bb || 944 | (x.bishops_bb == y.bishops_bb && 945 | (x.queens_bb < y.queens_bb || 946 | (x.queens_bb == y.queens_bb && 947 | (x.kings_bb < y.kings_bb || 948 | (x.kings_bb == y.kings_bb && 949 | (x.pawns_bb < y.pawns_bb || 950 | (x.pawns_bb == y.pawns_bb && 951 | (x.current_piece_bb < y.current_piece_bb || 952 | (x.current_piece_bb == y.current_piece_bb && 953 | (x.promotion_piece < y.promotion_piece))))))))))))))); 954 | } 955 | 956 | private uint64_t movepoints(gamestate g) 957 | { 958 | uint64_t movepoints = 0; 959 | iterator i = mkIterator(g); 960 | while (! is_iterator_finished(i)) { 961 | movepoints |= i.current_piece_bb; 962 | i.current_piece_bb = 0; 963 | i = advance_iterator(g, i); 964 | } 965 | return movepoints; 966 | } 967 | 968 | private uint64_t vulnerables(gamestate g) 969 | { 970 | g = swap_board(g); 971 | uint64_t ret = movepoints(g) & enemy_pieces(g); 972 | ret = flip_bb(ret); 973 | return ret; 974 | } 975 | 976 | private bool is_in_check(gamestate g) 977 | { 978 | uint64_t white_kings = g.kings_bb & g.current_player_bb; 979 | return ((white_kings & vulnerables(g)) != 0); 980 | } 981 | 982 | private bool results_in_check(gamestate g, move m) 983 | { 984 | gamestate g2 = swap_board(apply_move(g,m)); 985 | return is_in_check(g2); 986 | } 987 | 988 | private bool is_legal(gamestate g, move m) 989 | { 990 | if (results_in_check(g,m)) { 991 | return false; 992 | } 993 | move kingside_castle_part; kingside_castle_part.from = mkPosition(4,0); kingside_castle_part.to = mkPosition(5,0); 994 | move queenside_castle_part; queenside_castle_part.from = mkPosition(4,0); queenside_castle_part.to = mkPosition(3,0); 995 | bool valid_kingside_castle = 996 | is_kingside_castle(g, m) 997 | ? (! results_in_check(g, kingside_castle_part) && 998 | ! is_in_check(g)) 999 | : true; 1000 | bool valid_queenside_castle = 1001 | is_queenside_castle(g, m) 1002 | ? (! results_in_check(g, queenside_castle_part) && 1003 | ! is_in_check(g)) 1004 | : true; 1005 | return 1006 | valid_kingside_castle && 1007 | valid_queenside_castle; 1008 | } 1009 | 1010 | // Like advance_iterator, but skip moves that leave the king in check 1011 | private iterator advance_iterator_legal(gamestate g, iterator i) 1012 | { 1013 | while (1) { 1014 | i = advance_iterator(g, i); 1015 | if (is_iterator_finished(i)) { 1016 | break; 1017 | } 1018 | move m = dereference_iterator(i); 1019 | if (is_legal(g, m)) { 1020 | break; 1021 | } 1022 | } 1023 | return i; 1024 | } 1025 | 1026 | private iterator mkLegalIterator(gamestate g) 1027 | { 1028 | iterator i = mkIterator(g); 1029 | move m = dereference_iterator(i); 1030 | if (! is_legal(g, m)) { 1031 | i = advance_iterator_legal(g, i); 1032 | } 1033 | return i; 1034 | } 1035 | 1036 | private uint64_t legal_movepoints(gamestate g) 1037 | { 1038 | uint64_t movepoints = 0; 1039 | iterator i = mkLegalIterator(g); 1040 | while (! is_iterator_finished(i)) { 1041 | move m = dereference_iterator(i); 1042 | movepoints |= bit(m.to); 1043 | i = advance_iterator_legal(g, i); 1044 | } 1045 | return movepoints; 1046 | } 1047 | 1048 | private int num_legal_moves(gamestate g) 1049 | { 1050 | iterator i = mkLegalIterator(g); 1051 | int count = 0; 1052 | while (! is_iterator_finished(i)) { 1053 | i = advance_iterator_legal(g, i); 1054 | count++; 1055 | } 1056 | return count; 1057 | } 1058 | 1059 | private iterator legalize(gamestate g, iterator i) 1060 | { 1061 | while (! is_iterator_finished(i)) { 1062 | move m = dereference_iterator(i); 1063 | if (is_legal(g, m)) { 1064 | break; 1065 | } 1066 | i = advance_iterator(g, i); 1067 | } 1068 | return i; 1069 | } 1070 | 1071 | private uint64_t piece_legal_movepoints(gamestate g, int idx) 1072 | { 1073 | iterator i = zerostate(); 1074 | int piece = get_piece(g, idx); 1075 | i = set_piece_bb(i, piece, bit(idx)); 1076 | i = reset_iterator_moves(g, i); 1077 | i = legalize(g, i); 1078 | uint64_t ret = 0; 1079 | while (! is_iterator_finished(i)) { 1080 | move m = dereference_iterator(i); 1081 | ret |= bit(m.to); 1082 | i = advance_iterator_legal(g, i); 1083 | } 1084 | return ret; 1085 | } 1086 | 1087 | private move mkPromotion(int from, int piece) 1088 | { 1089 | if (rank(from) != 6) 1090 | abort(); 1091 | move m; 1092 | m.from = from; 1093 | m.to = from + RANK; 1094 | m.to |= piece << 6; 1095 | return m; 1096 | } 1097 | 1098 | // Public functions 1099 | // we could use __builtin_popcountl, but we'd need -march=native to eliminate library call which is less portable. 1100 | private uint64_t popcount64(uint64_t x) 1101 | { 1102 | x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL); 1103 | x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL); 1104 | x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL); 1105 | return (x * 0x0101010101010101ULL) >> 56; 1106 | } 1107 | private int num_bits(uint64_t x) { return popcount64(x); } 1108 | 1109 | private int score_pieces(gamestate g) 1110 | { 1111 | return 1112 | num_bits(g.pawns_bb & g.current_player_bb) * VALUE_PAWN + 1113 | num_bits(g.knights_bb & g.current_player_bb) * VALUE_KNIGHT + 1114 | num_bits(g.bishops_bb & g.current_player_bb) * VALUE_BISHOP + 1115 | num_bits(g.rooks_bb & g.current_player_bb) * VALUE_ROOK + 1116 | num_bits(g.queens_bb & g.current_player_bb) * VALUE_QUEEN; 1117 | } 1118 | 1119 | private int score_availability(gamestate g) 1120 | { 1121 | int num_moves = num_legal_moves(g); 1122 | if (num_moves == 0) 1123 | return VALUE_CHECKMATE; 1124 | return VALUE_AVAILABLE_MOVE * num_moves; 1125 | } 1126 | 1127 | private int score_attacking(gamestate g) 1128 | { 1129 | return num_bits(enemy_pieces(g) & movepoints(g)); 1130 | } 1131 | 1132 | private uint64_t center() 1133 | { 1134 | return 1135 | bit(mkPosition(2,2)) | 1136 | bit(mkPosition(2,3)) | 1137 | bit(mkPosition(2,4)) | 1138 | bit(mkPosition(2,5)) | 1139 | 1140 | bit(mkPosition(3,2)) | 1141 | bit(mkPosition(3,3)) | 1142 | bit(mkPosition(3,4)) | 1143 | bit(mkPosition(3,5)) | 1144 | 1145 | bit(mkPosition(4,2)) | 1146 | bit(mkPosition(4,3)) | 1147 | bit(mkPosition(4,4)) | 1148 | bit(mkPosition(4,5)) | 1149 | 1150 | bit(mkPosition(5,2)) | 1151 | bit(mkPosition(5,3)) | 1152 | bit(mkPosition(5,4)) | 1153 | bit(mkPosition(5,5)); 1154 | } 1155 | 1156 | private int score_center(gamestate g) 1157 | { 1158 | int num_centers = num_bits(g.current_player_bb & center()); 1159 | return num_centers * VALUE_CENTER; 1160 | } 1161 | 1162 | private int evaluate(gamestate g) 1163 | { 1164 | return score_pieces(g) + score_availability(g) + score_attacking(g); 1165 | } 1166 | 1167 | 1168 | typedef struct negamax_ret { 1169 | move m; 1170 | int score; 1171 | } negamax_ret; 1172 | 1173 | 1174 | private int negamax(gamestate g, int depth, int color) 1175 | { 1176 | if (depth == 0) 1177 | return color*evaluate(g); 1178 | int max = VALUE_NEGAMAX_START; 1179 | for (iterator i = mkLegalIterator(g); ! is_iterator_finished(i); i = advance_iterator_legal(g, i)) { 1180 | move m = dereference_iterator(i); 1181 | gamestate g2 = apply_move(g, m); 1182 | int score = -negamax(g2, depth-1, color*-1); 1183 | if (score > max) 1184 | max = score; 1185 | } 1186 | return max; 1187 | } 1188 | 1189 | private move best_move(gamestate g, int depth) 1190 | { 1191 | int max = VALUE_NEGAMAX_START; 1192 | move ret; ret.from = POSITION_INVALID; ret.to = POSITION_INVALID; 1193 | for (iterator i = mkLegalIterator(g); ! is_iterator_finished(i); i = advance_iterator_legal(g, i)) { 1194 | move m = dereference_iterator(i); 1195 | gamestate g2 = apply_move(g, m); 1196 | int score = -negamax(g2, depth, -1); 1197 | if (score > max) { 1198 | max = score; 1199 | ret = m; 1200 | } 1201 | } 1202 | return ret; 1203 | } 1204 | 1205 | private uint64_t perft(gamestate g, int depth) 1206 | { 1207 | if (depth == 0) { return 1; } 1208 | uint64_t n = 0; 1209 | for (iterator i = mkLegalIterator(g); ! is_iterator_finished(i); i = advance_iterator_legal(g, i)) { 1210 | move m = dereference_iterator(i); 1211 | gamestate g2 = apply_move(g, m); 1212 | n += perft(g2, depth-1); 1213 | } 1214 | return n; 1215 | } 1216 | 1217 | typedef struct packed_move { 1218 | union { 1219 | move m; 1220 | uint64_t packed; 1221 | }; 1222 | } packed_move; 1223 | 1224 | 1225 | private gamestate parse_fen(const char* s) 1226 | { 1227 | const char *orig_s = s; 1228 | // Pieces 1229 | gamestate g = zerostate(); 1230 | for (int r = 8; r --> 0;) { 1231 | for (int f = 0;; f++) { 1232 | int pos = mkPosition(f,r); 1233 | char c = *s++; 1234 | switch (c) { 1235 | case 'R': g.current_piece_bb |= bit(pos); 1236 | case 'r': g.rooks_bb |= bit(pos); break; 1237 | case 'N': g.current_piece_bb |= bit(pos); 1238 | case 'n': g.knights_bb |= bit(pos); break; 1239 | case 'B': g.current_piece_bb |= bit(pos); 1240 | case 'b': g.bishops_bb |= bit(pos); break; 1241 | case 'Q': g.current_piece_bb |= bit(pos); 1242 | case 'q': g.queens_bb |= bit(pos); break; 1243 | case 'K': g.current_piece_bb |= bit(pos); 1244 | case 'k': g.kings_bb |= bit(pos); break; 1245 | case 'P': g.current_piece_bb |= bit(pos); 1246 | case 'p': g.pawns_bb |= bit(pos); break; 1247 | case '8': f++; 1248 | case '7': f++; 1249 | case '6': f++; 1250 | case '5': f++; 1251 | case '4': f++; 1252 | case '3': f++; 1253 | case '2': f++; 1254 | case '1': break; 1255 | case '/': goto end_row; 1256 | case ' ': goto end_loop; 1257 | default: abort(); goto end_loop; 1258 | } 1259 | } 1260 | end_row:; 1261 | } 1262 | end_loop: 1263 | // Color 1264 | switch (*s++) { 1265 | case 'w': g.is_white = true; break; 1266 | case 'b': g.is_white = false; break; 1267 | default: abort(); 1268 | } 1269 | s++; 1270 | // Castle flags 1271 | while (*s != ' ') { 1272 | switch (*s++) { 1273 | case 'K': g.castle_flags |= CASTLE_WHITE_KINGSIDE; break; 1274 | case 'Q': g.castle_flags |= CASTLE_WHITE_QUEENSIDE; break; 1275 | case 'k': g.castle_flags |= CASTLE_BLACK_KINGSIDE; break; 1276 | case 'q': g.castle_flags |= CASTLE_BLACK_QUEENSIDE; break; 1277 | case '-': break; 1278 | default: abort(); 1279 | } 1280 | } 1281 | if (!g.is_white) { 1282 | g = swap_board(g); 1283 | } 1284 | return g; 1285 | } 1286 | 1287 | private char piece_char(int p, bool is_white) { 1288 | switch (p) { 1289 | case PIECE_EMPTY: return '.'; 1290 | case PIECE_ROOK: return is_white ? 'R' : 'r'; 1291 | case PIECE_KNIGHT: return is_white ? 'N' : 'n'; 1292 | case PIECE_BISHOP: return is_white ? 'B' : 'b'; 1293 | case PIECE_QUEEN: return is_white ? 'Q' : 'q'; 1294 | case PIECE_KING: return is_white ? 'K' : 'k'; 1295 | case PIECE_PAWN: return is_white ? 'P' : 'p'; 1296 | default: abort(); 1297 | } 1298 | } 1299 | 1300 | private void print_pos(int pos, char *buffer) 1301 | { 1302 | *buffer++ = file(pos) + 'a'; 1303 | *buffer++ = rank(pos) + '1'; 1304 | } 1305 | 1306 | private void print_fen(gamestate g, char *buffer) 1307 | { 1308 | bool swap = ! g.is_white; 1309 | if (swap) 1310 | g = swap_board(g); 1311 | int num_empty_squares = 0; 1312 | for (int r = 8; r --> 0;) { 1313 | for (int f = 0; f < 8; f++) { 1314 | int pos = mkPosition(f, r); 1315 | int piece = get_piece(g, pos); 1316 | if (piece == PIECE_EMPTY) { 1317 | num_empty_squares++; 1318 | continue; 1319 | } else if (num_empty_squares > 0) { 1320 | *buffer++ = (num_empty_squares + '0'); 1321 | num_empty_squares = 0; 1322 | } 1323 | bool is_white = is_bit_set(g.current_player_bb, pos); 1324 | char c = piece_char(piece, is_white); 1325 | *buffer++ = c; 1326 | } 1327 | if (num_empty_squares > 0) { 1328 | *buffer++ = (num_empty_squares + '0'); 1329 | num_empty_squares = 0; 1330 | } 1331 | if (r > 0) { 1332 | *buffer++ = '/'; 1333 | } 1334 | } 1335 | skip_loop: 1336 | *buffer++ = ' '; 1337 | *buffer++ = g.is_white 1338 | ? 'w' 1339 | : 'b'; 1340 | *buffer++ = ' '; 1341 | // Castle Flags 1342 | { 1343 | if (g.castle_flags & CASTLE_WHITE_KINGSIDE) 1344 | *buffer++ = 'K'; 1345 | if (g.castle_flags & CASTLE_WHITE_QUEENSIDE) 1346 | *buffer++ = 'Q'; 1347 | if (g.castle_flags & CASTLE_BLACK_KINGSIDE) 1348 | *buffer++ = 'k'; 1349 | if (g.castle_flags & CASTLE_BLACK_QUEENSIDE) 1350 | *buffer++ = 'q'; 1351 | if (! g.castle_flags) 1352 | *buffer++ = '-'; 1353 | } 1354 | *buffer++ = ' '; 1355 | if (g.en_passant_sq == POSITION_INVALID) { 1356 | *buffer++ = '-'; 1357 | } else { 1358 | //printf("%d---", g.en_passant_sq); 1359 | print_pos(g.en_passant_sq, buffer); 1360 | buffer += 2; 1361 | } 1362 | *buffer++ = ' '; 1363 | *buffer++ = '0'; 1364 | *buffer++ = ' '; 1365 | *buffer++ = '1'; 1366 | *buffer++ = 0; 1367 | } 1368 | 1369 | // Buffer must have at least 7 characters available 1370 | private void print_move(move m, char *buffer) 1371 | { 1372 | print_pos(m.from, buffer); buffer+=2; 1373 | print_pos(m.to & 0x3F, buffer); buffer+=2; 1374 | int piece = promotion_piece(m); 1375 | switch (piece) { 1376 | case PIECE_EMPTY: break; 1377 | case PIECE_ROOK: *buffer++ = '/'; *buffer++ = 'R'; break; 1378 | case PIECE_KNIGHT: *buffer++ = '/'; *buffer++ = 'N'; break; 1379 | case PIECE_BISHOP: *buffer++ = '/'; *buffer++ = 'B'; break; 1380 | case PIECE_QUEEN: *buffer++ = '/'; *buffer++ = 'Q'; break; 1381 | default: abort(); 1382 | } 1383 | *buffer++ = 0; 1384 | } 1385 | 1386 | private int parse_pos(const char* buffer) 1387 | { 1388 | int file = *buffer++ - 'a'; 1389 | int rank = *buffer++ - '1'; 1390 | return mkPosition(file, rank); 1391 | } 1392 | 1393 | private move parse_move(const char* buffer) 1394 | { 1395 | move m; 1396 | m.from = parse_pos(buffer); 1397 | buffer += 2; 1398 | m.to = parse_pos(buffer); 1399 | buffer += 2; 1400 | if (*buffer) { 1401 | buffer++; 1402 | switch (*buffer++) { 1403 | case 'R': m.to |= (PIECE_ROOK << 6); break; 1404 | case 'N': m.to |= (PIECE_KNIGHT << 6); break; 1405 | case 'B': m.to |= (PIECE_BISHOP << 6); break; 1406 | case 'Q': m.to |= (PIECE_QUEEN << 6); break; 1407 | default: abort(); 1408 | } 1409 | } 1410 | return m; 1411 | } 1412 | 1413 | // Used when generating pf_best_move 1414 | /* extern "C" void custom_main(const char *g_str, char *m_dest, int depth) */ 1415 | /* { */ 1416 | /* gamestate g = parse_fen(g_str); */ 1417 | /* move m = best_move(g, depth); */ 1418 | /* if (! g.is_white) */ 1419 | /* m = swap_move(m); */ 1420 | /* print_move(m, m_dest); */ 1421 | /* } */ 1422 | 1423 | // Used when generating pf_apply_move 1424 | extern "C" void custom_main(const char *g_str, const char *m_str, char *g_dest) 1425 | { 1426 | gamestate g = parse_fen(g_str); 1427 | move m = parse_move(m_str); 1428 | if (! g.is_white) 1429 | m = swap_move(m); 1430 | gamestate g2 = apply_move(g, m); 1431 | print_fen(g2, g_dest); 1432 | } 1433 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | g++ -c chess.c \ 4 | -O3 \ 5 | -fPIC \ 6 | -fno-jump-tables 7 | 8 | bash -c 'cd dump-elf-bytes; stack exec dump-elf-bytes -- ../chess.o > ../shellcode_bytes.py' 9 | -------------------------------------------------------------------------------- /dump-elf-bytes/.gitignore: -------------------------------------------------------------------------------- 1 | .stack-work/ 2 | -------------------------------------------------------------------------------- /dump-elf-bytes/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Michael Burge (c) 2017 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Michael Burge nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /dump-elf-bytes/README.md: -------------------------------------------------------------------------------- 1 | # dump-elf-bytes 2 | -------------------------------------------------------------------------------- /dump-elf-bytes/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /dump-elf-bytes/app/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings, ViewPatterns #-} 2 | 3 | module Main where 4 | 5 | import Data.Elf 6 | import System.Environment 7 | import Data.ByteString as BS hiding (map) 8 | import Data.ByteString.Builder as BSB 9 | import Data.ByteString.Builder.Prim as BSB (primFixed) 10 | import qualified Data.ByteString.Lazy as BSL 11 | import Data.List 12 | import Data.Semigroup 13 | import Data.Word 14 | import qualified Data.Text.Lazy as TL 15 | import qualified Data.Text.Lazy.Encoding as TL 16 | import Prelude hiding (readFile) 17 | 18 | main :: IO () 19 | main = do 20 | [filename] <- getArgs 21 | bs <- readFile filename 22 | let elf = parseElf bs 23 | dumpElf elf 24 | 25 | dumpElf :: Elf -> IO () 26 | dumpElf elf = do 27 | let ss = elfSections elf 28 | sectionsByName = map (\s -> (elfSectionName s, s)) ss 29 | case lookup ".text" sectionsByName of 30 | Nothing -> error "No .text section found" 31 | Just s -> do 32 | -- Output actual shellcode 33 | BSL.putStr "shellcode = b'" 34 | dumpPythonBytes $ elfSectionData s 35 | BSL.putStr "'\n" 36 | -- Output offset to the "main" function 37 | let offset = getOffset elf 38 | BSL.putStr "offset = " 39 | BSL.putStr $ TL.encodeUtf8 $ TL.pack $ show offset 40 | BSL.putStr "\n" 41 | 42 | return () 43 | 44 | getOffset :: Elf -> Word64 45 | getOffset elf = 46 | let stes = Prelude.concat $ parseSymbolTables elf 47 | textStes = [ x | x@EST { steEnclosingSection = Just (ElfSection { elfSectionName = ".text" }) } <- stes ] 48 | mainStes = [ x | x@EST { steName = (_, Just "custom_main")} <- textStes ] 49 | mainOs = Prelude.map steValue mainStes 50 | in case mainOs of 51 | [x] -> x 52 | [] -> error "No main functions found" 53 | _ -> error $ "Multiple main functions found: " ++ show mainStes 54 | 55 | dumpPythonBytes :: ByteString -> IO () 56 | dumpPythonBytes bs = case BS.uncons bs of 57 | Nothing -> return () 58 | Just (b, bs') -> do 59 | putByte b 60 | dumpPythonBytes bs' 61 | where 62 | putByte b = do 63 | BSL.putStr $ BSB.toLazyByteString $ "\\x" <> word8HexFixed b 64 | -------------------------------------------------------------------------------- /dump-elf-bytes/dump-elf-bytes.cabal: -------------------------------------------------------------------------------- 1 | name: dump-elf-bytes 2 | version: 0.1.0.0 3 | -- synopsis: 4 | -- description: 5 | homepage: https://github.com/MichaelBurge/dump-elf-bytes#readme 6 | license: BSD3 7 | license-file: LICENSE 8 | author: Michael Burge 9 | maintainer: michaelburge@pobox.com 10 | copyright: 2017 Michael Burge 11 | category: Web 12 | build-type: Simple 13 | extra-source-files: README.md 14 | cabal-version: >=1.10 15 | 16 | executable dump-elf-bytes 17 | hs-source-dirs: app 18 | main-is: Main.hs 19 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 20 | build-depends: base 21 | , elf 22 | , bytestring 23 | , text 24 | default-language: Haskell2010 25 | 26 | source-repository head 27 | type: git 28 | location: https://github.com/MichaelBurge/dump-elf-bytes 29 | -------------------------------------------------------------------------------- /dump-elf-bytes/src/Lib.hs: -------------------------------------------------------------------------------- 1 | module Lib 2 | ( someFunc 3 | ) where 4 | 5 | someFunc :: IO () 6 | someFunc = putStrLn "someFunc" 7 | -------------------------------------------------------------------------------- /dump-elf-bytes/stack.yaml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by 'stack init' 2 | # 3 | # Some commonly used options have been documented as comments in this file. 4 | # For advanced use and comprehensive documentation of the format, please see: 5 | # https://docs.haskellstack.org/en/stable/yaml_configuration/ 6 | 7 | # Resolver to choose a 'specific' stackage snapshot or a compiler version. 8 | # A snapshot resolver dictates the compiler version and the set of packages 9 | # to be used for project dependencies. For example: 10 | # 11 | # resolver: lts-3.5 12 | # resolver: nightly-2015-09-21 13 | # resolver: ghc-7.10.2 14 | # resolver: ghcjs-0.1.0_ghc-7.10.2 15 | # resolver: 16 | # name: custom-snapshot 17 | # location: "./custom-snapshot.yaml" 18 | resolver: lts-9.3 19 | 20 | # User packages to be built. 21 | # Various formats can be used as shown in the example below. 22 | # 23 | # packages: 24 | # - some-directory 25 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz 26 | # - location: 27 | # git: https://github.com/commercialhaskell/stack.git 28 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a 29 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a 30 | # extra-dep: true 31 | # subdirs: 32 | # - auto-update 33 | # - wai 34 | # 35 | # A package marked 'extra-dep: true' will only be built if demanded by a 36 | # non-dependency (i.e. a user package), and its test suites and benchmarks 37 | # will not be run. This is useful for tweaking upstream packages. 38 | packages: 39 | - . 40 | # Dependency packages to be pulled from upstream that are not in the resolver 41 | # (e.g., acme-missiles-0.3) 42 | extra-deps: [elf-0.28] 43 | 44 | # Override default flag values for local packages and extra-deps 45 | flags: {} 46 | 47 | # Extra package databases containing global packages 48 | extra-package-dbs: [] 49 | 50 | # Control whether we use the GHC we find on the path 51 | # system-ghc: true 52 | # 53 | # Require a specific version of stack, using version ranges 54 | # require-stack-version: -any # Default 55 | # require-stack-version: ">=1.5" 56 | # 57 | # Override the architecture used by stack, especially useful on Windows 58 | # arch: i386 59 | # arch: x86_64 60 | # 61 | # Extra directories used by stack for building 62 | # extra-include-dirs: [/path/to/dir] 63 | # extra-lib-dirs: [/path/to/dir] 64 | # 65 | # Allow a newer minor version of GHC than the snapshot specifies 66 | # compiler-check: newer-minor 67 | -------------------------------------------------------------------------------- /dump-elf-bytes/test/Spec.hs: -------------------------------------------------------------------------------- 1 | main :: IO () 2 | main = putStrLn "Test suite not yet implemented" 3 | -------------------------------------------------------------------------------- /loader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Simple-1: gcc -c -O simple-1.c 8 | /* char shellcode[] = "\xb8\x2a\x00\x00\x00\xc3"; */ 9 | /* int offset = 0; */ 10 | // Simple-2: gcc -c -O simple-2.c 11 | /* char shellcode[] = "\xb8\x01\x00\x00\x00\x85\xff\x74\x0f\x53\x89\xfb\x8d\x7f\xff\xe8\xec\xff\xff\xff\x0f\xaf\xc3\x5b\xf3\xc3\x41\x54\x55\x53\x85\xff\x7e\x20\x41\x89\xfc\xbb\x00\x00\x00\x00\xbd\x00\x00\x00\x00\x89\xdf\xe8\xca\xff\xff\xff\x01\xc5\x83\xc3\x01\x41\x39\xdc\x75\xef\xeb\x05\xbd\x00\x00\x00\x00\x89\xe8\x5b\x5d\x41\x5c\xc3"; */ 12 | /* int offset = 26; */ 13 | 14 | // Chess 15 | #include "chess.bytes" 16 | 17 | void print_hex(char *start, char *end) 18 | { 19 | for (char c; start < end; start++) { 20 | c = *start; 21 | fprintf(stderr, "%02hhx", c); 22 | } 23 | putchar('\n'); 24 | } 25 | 26 | 27 | typedef struct gamestate { 28 | uint64_t rooks; 29 | uint64_t knights; 30 | uint64_t bishops; 31 | uint64_t queens; 32 | uint64_t kings; 33 | uint64_t pawns; 34 | union { 35 | uint64_t player; 36 | uint64_t current_piece_bb; // For iterators 37 | }; 38 | int en_passant_sq; 39 | union { 40 | uint64_t castle_flags; 41 | uint64_t promotion_piece; // For iterators 42 | }; 43 | } gamestate; 44 | 45 | typedef void (*shellcode_t)(const char*, char*); 46 | void invoke(shellcode_t f, const char* g, char* m) { f(g, m); } 47 | 48 | extern "C" uint64_t custom_main(gamestate); 49 | 50 | int main() { 51 | int size = sizeof(shellcode)-1; 52 | char *src_ptr = shellcode; 53 | void *code_ptr = valloc(size); 54 | printf("Codebase: %08x\n", code_ptr); 55 | memmove(code_ptr, src_ptr, size); 56 | int err = mprotect(code_ptr, size, 0x7); 57 | if (0 != err) { 58 | fprintf(stderr, "mprotect: %d\n", err); 59 | return 1; 60 | } 61 | shellcode_t f = (shellcode_t)(code_ptr+offset); 62 | /* print_hex(f, code_ptr + size); */ 63 | const char* fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"; 64 | char move_buf[10]; 65 | invoke(f, fen, move_buf); 66 | printf("%s\n", move_buf); 67 | free(code_ptr); 68 | 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /loader_apply_move.py: -------------------------------------------------------------------------------- 1 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE, c_uint64, c_int, c_char, create_string_buffer) 2 | 3 | from shellcode_bytes import shellcode, offset 4 | #shellcode = b'\xb8\x2a\x00\x00\x00\xc3' 5 | #offset = 26 6 | fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1" 7 | move = "e1f1" 8 | 9 | def execute(): 10 | libc = CDLL('libc.so.6') 11 | 12 | src_ptr = c_char_p(shellcode) 13 | size = len(shellcode) 14 | 15 | code_ptr = libc.valloc(size) 16 | code_ptr = c_void_p(code_ptr) 17 | 18 | memmove(code_ptr, src_ptr, size) 19 | err = libc.mprotect(code_ptr, size, 0x7) 20 | if 0 != err: 21 | raise Exception("mprotect: " + str(code)) 22 | 23 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 24 | 25 | result_buf = create_string_buffer(300) 26 | SHELLCODE_T = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p) 27 | 28 | fptr = cast(main_ptr, SHELLCODE_T) 29 | fptr(fen, move, result_buf) 30 | libc.free(code_ptr) 31 | return result_buf.raw 32 | 33 | print execute() 34 | -------------------------------------------------------------------------------- /loader_best_move.py: -------------------------------------------------------------------------------- 1 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE, c_uint64, c_int, c_char, create_string_buffer) 2 | 3 | from shellcode_bytes import shellcode, offset 4 | #shellcode = b'\xb8\x2a\x00\x00\x00\xc3' 5 | #offset = 26 6 | fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1" 7 | depth = 2 8 | 9 | def execute(): 10 | libc = CDLL('libc.so.6') 11 | 12 | src_ptr = c_char_p(shellcode) 13 | size = len(shellcode) 14 | 15 | code_ptr = libc.valloc(size) 16 | code_ptr = c_void_p(code_ptr) 17 | 18 | memmove(code_ptr, src_ptr, size) 19 | err = libc.mprotect(code_ptr, size, 0x7) 20 | if 0 != err: 21 | raise Exception("mprotect: " + str(code)) 22 | 23 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 24 | 25 | result_buf = create_string_buffer(10) 26 | SHELLCODE_T = CFUNCTYPE(None, c_char_p, c_char_p, c_int) 27 | 28 | fptr = cast(main_ptr, SHELLCODE_T) 29 | fptr(fen, result_buf, depth) 30 | libc.free(code_ptr) 31 | return result_buf.raw 32 | 33 | print execute() 34 | -------------------------------------------------------------------------------- /mmap-test.c: -------------------------------------------------------------------------------- 1 | // To manually assign an entry address: gcc mmap-test.c -Wl,-Ttext-segment=0x8000000 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | char shellcode[] = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3\x55\x48\x89\xe5\xb8\x00\x00\x00\x00\xba\x00\x00\x00\x40\xff\xd2\x48\x98\x5d\xc3"; 11 | int offset = 11; 12 | void *entry_address = (void*)(0x40000000); 13 | 14 | typedef int (*shellcode_t)(); 15 | 16 | int main() 17 | { 18 | char *src_ptr = shellcode; 19 | int size = sizeof(shellcode)-1; 20 | void *code_ptr = mmap(entry_address, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); 21 | if (code_ptr == MAP_FAILED) { 22 | err(1, "mmap failed"); 23 | return 1; 24 | } 25 | memmove(code_ptr, src_ptr, size); 26 | shellcode_t f = (shellcode_t)(code_ptr + offset); 27 | int result = f(); 28 | printf("%d\n", result); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /mmap-test.py: -------------------------------------------------------------------------------- 1 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE, c_uint64, Structure, c_int, c_char, create_string_buffer) 2 | 3 | #from shellcode_bytes import shellcode, offset 4 | shellcode = b'\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3\x55\x48\x89\xe5\xb8\x00\x00\x00\x00\xba\x00\x00\x40\x00\xff\xd2\x48\x98\x5d\xc3'; 5 | offset = 11 6 | #offset = 26 7 | entry_address = 0x400000 8 | 9 | MAP_FLAGS = 0x32 10 | 11 | def execute(): 12 | libc = CDLL('libc.so.6') 13 | 14 | src_ptr = c_char_p(shellcode) 15 | size = len(shellcode) 16 | 17 | code_ptr = libc.mmap(entry_address, size, 0x7, MAP_FLAGS, -1, 0) 18 | if (code_ptr == -1): 19 | libc.err(1, "mmap failed") 20 | return "" 21 | code_ptr = c_void_p(code_ptr) 22 | memmove(code_ptr, src_ptr, size) 23 | 24 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 25 | SHELLCODE_T = CFUNCTYPE(c_long) 26 | 27 | fptr = cast(main_ptr, SHELLCODE_T) 28 | result = fptr() 29 | #fptr(fen, move, result_buf) 30 | # libc.free(code_ptr) 31 | return result 32 | 33 | print(execute()) 34 | -------------------------------------------------------------------------------- /shellcode_bytes.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MichaelBurge/redshift-shellcode/1a690f42a7f06064c2f952bf85ae0b61b5b3f42b/shellcode_bytes.py -------------------------------------------------------------------------------- /sql/create-apply-move.sql: -------------------------------------------------------------------------------- 1 | create or replace function pf_apply_move (fen varchar, move varchar) returns varchar stable as $$ 2 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, Structure, CFUNCTYPE, c_uint64, c_int, create_string_buffer) 3 | 4 | def execute(): 5 | shellcode = b'\x83\xfe\x03\x0f\x84\x67\x01\x00\x00\x7e\x55\x83\xfe\x05\x0f\x84\x1c\x01\x00\x00\x0f\x8c\xbe\x00\x00\x00\x83\xfe\x06\x0f\x85\xad\x00\x00\x00\x48\x8b\x44\x24\x08\x48\x89\x54\x24\x30\x48\x89\x57\x28\x48\x89\x07\x48\x8b\x44\x24\x10\x48\x89\x47\x08\x48\x8b\x44\x24\x18\x48\x89\x47\x10\x48\x8b\x44\x24\x20\x48\x89\x47\x18\x48\x8b\x44\x24\x28\x48\x89\x47\x20\xeb\x49\x66\x0f\x1f\x44\x00\x00\x83\xfe\x01\x0f\x84\xa7\x00\x00\x00\x83\xfe\x02\x75\x62\x48\x8b\x44\x24\x08\x48\x89\x54\x24\x10\x48\x89\x57\x08\x48\x89\x07\x48\x8b\x44\x24\x18\x48\x89\x47\x10\x48\x8b\x44\x24\x20\x48\x89\x47\x18\x48\x8b\x44\x24\x28\x48\x89\x47\x20\x48\x8b\x44\x24\x30\x48\x89\x47\x28\x48\x8b\x44\x24\x38\x48\x89\x47\x30\x48\x8b\x44\x24\x40\x48\x89\x47\x38\x48\x8b\x44\x24\x48\x48\x89\x47\x40\x48\x8b\x44\x24\x50\x48\x89\x47\x48\x48\x89\xf8\xc3\x0f\x1f\x44\x00\x00\x0f\x0b\x66\x0f\x1f\x44\x00\x00\x48\x8b\x44\x24\x08\x48\x89\x54\x24\x20\x48\x89\x57\x18\x48\x89\x07\x48\x8b\x44\x24\x10\x48\x89\x47\x08\x48\x8b\x44\x24\x18\x48\x89\x47\x10\x48\x8b\x44\x24\x28\x48\x89\x47\x20\x48\x8b\x44\x24\x30\x48\x89\x47\x28\xeb\x94\x90\x48\x8b\x44\x24\x10\x48\x89\x54\x24\x08\x48\x89\x17\x48\x89\x47\x08\x48\x8b\x44\x24\x18\x48\x89\x47\x10\xe9\x59\xff\xff\xff\x90\x48\x8b\x44\x24\x08\x48\x89\x54\x24\x28\x48\x89\x57\x20\x48\x89\x07\x48\x8b\x44\x24\x10\x48\x89\x47\x08\x48\x8b\x44\x24\x18\x48\x89\x47\x10\x48\x8b\x44\x24\x20\x48\x89\x47\x18\x48\x8b\x44\x24\x30\x48\x89\x47\x28\xe9\x39\xff\xff\xff\x66\x0f\x1f\x44\x00\x00\x48\x8b\x44\x24\x08\x48\x89\x54\x24\x18\x48\x89\x57\x10\x48\x89\x07\x48\x8b\x44\x24\x10\x48\x89\x47\x08\xe9\xf9\xfe\xff\xff\x90\x49\x89\xca\x48\x63\x4c\x24\x08\x31\xc0\x48\x83\xf9\x3f\x77\x15\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\x89\xc1\xb8\x01\x00\x00\x00\x48\x85\xcf\x74\x0b\xf3\xc3\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x85\xce\x74\x06\xb8\x02\x00\x00\x00\xc3\x48\x85\xca\x74\x06\xb8\x03\x00\x00\x00\xc3\x49\x85\xca\x74\x06\xb8\x04\x00\x00\x00\xc3\x49\x85\xc8\x74\x06\xb8\x05\x00\x00\x00\xc3\x4c\x21\xc9\x48\x83\xf9\x01\x19\xc0\xf7\xd0\x83\xe0\x06\xc3\x0f\x1f\x44\x00\x00\x41\x57\x41\x56\x45\x31\xff\x41\x55\x41\x54\x45\x31\xf6\x55\x53\x45\x31\xed\x45\x31\xe4\x31\xed\x31\xdb\x48\x81\xec\xe8\x01\x00\x00\x45\x31\xdb\x41\xb8\x01\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\xd8\x01\x00\x00\x31\xc0\x48\x89\x14\x24\xba\x38\x00\x00\x00\x31\xc0\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x83\xc7\x01\x44\x0f\xb6\x4f\xff\x8d\x0c\x10\x48\x63\xc9\x41\x80\xf9\x42\x0f\x84\xd7\x01\x00\x00\x7f\x55\x41\x80\xf9\x33\x74\x42\x0f\x8e\x09\x01\x00\x00\x41\x80\xf9\x36\x74\x2d\x7f\x19\x41\x80\xf9\x34\x74\x2b\x41\x80\xf9\x35\x74\x22\x0f\x1f\x44\x00\x00\x0f\x0b\x66\x0f\x1f\x44\x00\x00\x41\x80\xf9\x37\x74\x09\x41\x80\xf9\x38\x75\xec\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\x83\xc0\x01\xeb\x92\x66\x90\x41\x80\xf9\x62\x0f\x84\x8d\x01\x00\x00\x7f\x3c\x41\x80\xf9\x50\x0f\x84\x32\x01\x00\x00\x0f\x8f\xec\x00\x00\x00\x41\x80\xf9\x4b\x74\x66\x41\x80\xf9\x4e\x75\xa8\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\xeb\x27\x0f\x1f\x80\x00\x00\x00\x00\x41\x80\xf9\x70\x0f\x84\x0d\x01\x00\x00\x0f\x8f\x98\x00\x00\x00\x41\x80\xf9\x6b\x74\x41\x41\x80\xf9\x6e\x0f\x85\x68\xff\xff\xff\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4d\x09\xce\xe9\x76\xff\xff\xff\x0f\x1f\x44\x00\x00\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4c\x09\xcd\xe9\x3f\xff\xff\xff\x66\x0f\x1f\x44\x00\x00\x41\x80\xf9\x2f\x0f\x84\x96\x08\x00\x00\x0f\x8e\x28\x01\x00\x00\x41\x80\xf9\x31\x0f\x84\x1f\xff\xff\xff\x41\x80\xf9\x32\x0f\x84\x12\xff\xff\xff\x0f\x0b\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x41\x80\xf9\x71\x74\x33\x41\x80\xf9\x72\x0f\x84\xd9\x00\x00\x00\x0f\x0b\x66\x0f\x1f\x44\x00\x00\x41\x80\xf9\x51\x0f\x85\xa6\x00\x00\x00\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4d\x09\xcc\xe9\xb5\xfe\xff\xff\x0f\x1f\x40\x00\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4c\x09\xcb\xe9\x7f\xfe\xff\xff\x66\x0f\x1f\x44\x00\x00\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4d\x09\xcd\xe9\x47\xfe\xff\xff\x66\x0f\x1f\x44\x00\x00\x41\x80\xf9\x52\x0f\x85\x0e\xfe\xff\xff\x4d\x89\xc1\x41\xba\x00\x00\x00\x00\x49\xd3\xe1\x48\x83\xf9\x3f\x4d\x0f\x47\xca\x4d\x09\xcb\x4d\x89\xc1\x49\xd3\xe1\x48\x83\xf9\x3f\xb9\x00\x00\x00\x00\x4c\x0f\x47\xc9\x4d\x09\xcf\xe9\x05\xfe\xff\xff\x0f\x1f\x40\x00\x41\x80\xf9\x20\x0f\x85\xce\xfd\xff\xff\x0f\xb6\x07\x3c\x62\x0f\x84\x6a\x07\x00\x00\x3c\x77\x0f\x85\xbb\xfd\xff\xff\xba\x01\x00\x00\x00\xc6\x44\x24\x08\x01\x48\x83\xc7\x02\x45\x31\xd2\x0f\xb6\x07\x3c\x20\x74\x29\x48\x83\xc7\x01\x3c\x51\x0f\x84\x67\x07\x00\x00\x0f\x8f\x49\x07\x00\x00\x3c\x2d\x74\xe3\x3c\x4b\x0f\x85\x85\xfd\xff\xff\x0f\xb6\x07\x49\x83\xca\x01\x3c\x20\x75\xd7\x84\xd2\x0f\x85\x81\x01\x00\x00\x0f\xb6\x7c\x24\x08\xc7\x84\x24\xc8\x00\x00\x00\xff\x00\x00\x00\x48\x8b\x84\x24\xc8\x00\x00\x00\x40\x88\xbc\x24\xd8\x00\x00\x00\x48\x89\x84\x24\x18\x01\x00\x00\x48\x8b\x84\x24\xd8\x00\x00\x00\xc7\x84\x24\x18\x01\x00\x00\xff\x00\x00\x00\x48\x89\x84\x24\x28\x01\x00\x00\x4c\x89\xf0\x40\x88\xbc\x24\x28\x01\x00\x00\x4c\x09\xf8\x49\x0f\xce\x49\x0f\xcf\x4c\x09\xe8\x49\x0f\xcd\x4c\x89\xbc\x24\xe0\x00\x00\x00\x4c\x09\xe0\x49\x0f\xcc\x4c\x89\xb4\x24\xe8\x00\x00\x00\x48\x09\xe8\x48\x0f\xcd\x4c\x89\xac\x24\xf0\x00\x00\x00\x48\x09\xd8\x48\x0f\xcb\x4c\x89\xa4\x24\xf8\x00\x00\x00\x49\x31\xc3\x4c\x89\xd0\x48\x89\xac\x24\x00\x01\x00\x00\x83\xe0\x01\x49\x0f\xcb\x48\x89\x9c\x24\x08\x01\x00\x00\x48\x83\xf8\x01\x4c\x89\x9c\x24\x10\x01\x00\x00\x4c\x89\xbc\x24\x30\x01\x00\x00\x19\xc9\xf7\xd8\x4c\x89\xb4\x24\x38\x01\x00\x00\x83\xe1\xfc\x83\xe0\x04\x4c\x89\xac\x24\x40\x01\x00\x00\x83\xc1\x0c\x41\xf6\xc2\x02\x4c\x89\xa4\x24\x48\x01\x00\x00\x0f\x45\xc1\x48\x89\xac\x24\x50\x01\x00\x00\x48\x89\x9c\x24\x58\x01\x00\x00\x89\xc1\x4c\x89\x9c\x24\x60\x01\x00\x00\x83\xc9\x01\x41\xf6\xc2\x04\x0f\x45\xc1\x89\xc1\x83\xc9\x02\x41\x83\xe2\x08\x0f\x45\xc1\x4c\x63\xd0\x48\x8b\x84\x24\x18\x01\x00\x00\x4c\x89\x94\x24\x20\x01\x00\x00\x4c\x89\x94\x24\x70\x01\x00\x00\x48\x89\x84\x24\x68\x01\x00\x00\x48\x8b\x84\x24\x28\x01\x00\x00\xc7\x84\x24\x68\x01\x00\x00\xff\x00\x00\x00\x48\x89\x84\x24\x78\x01\x00\x00\x48\x8b\x84\x24\x68\x01\x00\x00\x40\x88\xbc\x24\x78\x01\x00\x00\x48\x89\x84\x24\xc8\x00\x00\x00\x48\x8b\x84\x24\x78\x01\x00\x00\x48\x89\x84\x24\xd8\x00\x00\x00\x0f\xbe\x4e\x01\x0f\xbe\x06\x80\x7e\x04\x00\x8d\x84\xc8\x17\xfe\xff\xff\x0f\xbe\x4e\x03\x89\x44\x24\x10\x0f\xbe\x46\x02\x8d\x84\xc8\x17\xfe\xff\xff\x89\x44\x24\x18\x74\x27\x0f\xb6\x46\x05\x3c\x4e\x0f\x84\x98\x06\x00\x00\x0f\x8e\x29\x0a\x00\x00\x3c\x51\x0f\x84\x7c\x0a\x00\x00\x83\x4c\x24\x18\x40\x3c\x52\x0f\x85\x9f\xfb\xff\xff\x84\xd2\x75\x5d\x8b\x74\x24\x10\xb9\x07\x00\x00\x00\x89\xf2\x89\xf0\xc1\xfa\x1f\xc1\xea\x1d\x01\xd0\x83\xe0\x07\x29\xd0\x89\xf2\x83\xc2\x07\x85\xf6\x0f\x49\xd6\x89\xce\xc1\xfa\x03\x29\xd6\x8d\x04\xf0\x8b\x74\x24\x18\x89\x44\x24\x10\x89\xf2\x89\xf0\xc1\xfa\x1f\xc1\xea\x1d\x01\xd0\x83\xe0\x07\x29\xd0\x89\xf2\x83\xc2\x07\x85\xf6\x0f\x49\xd6\xc1\xfa\x03\x29\xd1\x8d\x04\xc8\x89\x44\x24\x18\x0f\xb6\x44\x24\x08\xc7\x84\x24\xc8\x00\x00\x00\xff\x00\x00\x00\x49\x89\xd9\x4c\x89\x94\x24\xd0\x00\x00\x00\x4c\x89\x54\x24\x30\x49\x89\xe8\x4c\x89\x9c\x24\xc0\x00\x00\x00\x4c\x89\xbc\x24\x90\x00\x00\x00\x4c\x89\xe1\x4c\x89\xb4\x24\x98\x00\x00\x00\x4c\x89\xac\x24\xa0\x00\x00\x00\x4c\x89\xea\x88\x84\x24\xd8\x00\x00\x00\x48\x8b\x84\x24\xc8\x00\x00\x00\x4c\x89\xf6\x4c\x89\xa4\x24\xa8\x00\x00\x00\x48\x89\xac\x24\xb0\x00\x00\x00\x4c\x89\xff\x48\x89\x9c\x24\xb8\x00\x00\x00\x48\x89\x84\x24\xb8\x01\x00\x00\x48\x8b\x84\x24\xd8\x00\x00\x00\x48\x89\x84\x24\xc8\x01\x00\x00\x8b\x44\x24\x10\x50\xe8\xa6\xf9\xff\xff\x8b\x74\x24\x20\x89\x44\x24\x28\x49\x89\xe8\x4c\x89\xe1\x49\x89\xd9\x4c\x89\xea\x4c\x89\xff\x89\xf0\xc1\xf8\x06\x89\x44\x24\x30\x89\xf0\x4c\x89\xf6\x83\xe0\x3f\x89\x44\x24\x20\x89\x04\x24\xe8\x72\xf9\xff\xff\x59\x85\xc0\x41\x89\xc0\x4c\x8b\x54\x24\x30\x0f\x85\x4a\x04\x00\x00\x4c\x89\xd6\xb8\xff\x00\x00\x00\x8b\x54\x24\x28\x85\xd2\x0f\x85\x05\x07\x00\x00\x8b\x7c\x24\x20\x83\xff\x03\x0f\x84\x72\x09\x00\x00\x0f\x8e\xdc\x08\x00\x00\x83\xff\x05\x0f\x84\x6b\x09\x00\x00\x0f\x8c\x6d\x09\x00\x00\x83\xff\x06\x48\x89\xda\x0f\x85\x1f\xfa\xff\xff\x4c\x63\x4c\x24\x10\x48\x63\x7c\x24\x18\x49\x83\xf9\x3f\x48\x89\x7c\x24\x28\x77\x10\x48\xc7\xc7\xfe\xff\xff\xff\x44\x89\xc9\x48\xd3\xc7\x48\x21\xfa\x0f\xb6\x4c\x24\x28\x89\x84\x24\xb8\x01\x00\x00\xbf\x01\x00\x00\x00\x0f\xb6\x44\x24\x08\x4c\x89\x54\x24\x38\x48\xd3\xe7\x48\x89\x7c\x24\x30\x88\x84\x24\xc8\x01\x00\x00\x48\x89\xf9\x48\x8d\x7c\x24\x40\xff\xb4\x24\xc8\x01\x00\x00\x56\xff\xb4\x24\xc8\x01\x00\x00\x41\x53\x48\x09\xca\x53\x55\x41\x54\x41\x55\x41\x56\x41\x57\x8b\x74\x24\x70\xe8\x11\xf7\xff\xff\x48\x8b\x8c\x24\xa0\x00\x00\x00\x48\x8b\x94\x24\xc8\x00\x00\x00\x48\x8b\xac\x24\xd0\x00\x00\x00\x4c\x8b\xa4\x24\xd8\x00\x00\x00\x48\x8b\xb4\x24\x90\x00\x00\x00\x4c\x8b\xac\x24\x98\x00\x00\x00\x4c\x8b\x9c\x24\xa8\x00\x00\x00\x48\x8b\x9c\x24\xb0\x00\x00\x00\x48\x8b\xbc\x24\xb8\x00\x00\x00\x48\x8b\x84\x24\xc0\x00\x00\x00\x45\x89\xe6\x48\x89\x8c\x24\xe0\x01\x00\x00\x48\x89\x94\x24\x08\x02\x00\x00\x48\x89\x4c\x24\x58\x48\x89\xb4\x24\xd0\x01\x00\x00\x89\xd1\x4c\x89\xac\x24\xd8\x01\x00\x00\x4c\x89\x9c\x24\xe8\x01\x00\x00\x48\x89\xea\x48\x89\x9c\x24\xf0\x01\x00\x00\x48\x89\xbc\x24\xf8\x01\x00\x00\x48\x89\x84\x24\x00\x02\x00\x00\x48\x89\xac\x24\x10\x02\x00\x00\x4c\x89\xa4\x24\x18\x02\x00\x00\x48\x83\xc4\x50\x4c\x8b\x54\x24\x38\x83\x7c\x24\x20\x06\x0f\x84\x14\x07\x00\x00\x83\x7c\x24\x20\x05\x40\x0f\x94\xc5\x83\x7c\x24\x18\x06\x0f\x94\xc1\x40\x20\xe9\x0f\x84\x8e\x08\x00\x00\x41\xf6\xc2\x01\x74\x12\x40\x80\xe6\x7f\x24\x7f\x48\x83\xe2\xfe\x48\x83\xce\x20\x48\x83\xc8\x20\x83\x7c\x24\x18\x02\x41\x0f\x94\xc7\x41\x20\xcf\x0f\x84\x54\x08\x00\x00\x41\x83\xe2\x02\x0f\x85\xf6\x05\x00\x00\xbd\xff\x00\x00\x00\x83\x7c\x24\x20\x01\x0f\x94\xc1\x83\x7c\x24\x10\x07\x41\x0f\x94\xc4\x41\x84\xcc\x74\x0e\x49\x89\xd4\x49\x83\xe4\xfe\xf6\xc2\x01\x49\x0f\x45\xd4\x44\x8b\x54\x24\x10\x45\x85\xd2\x41\x0f\x94\xc4\x41\x84\xcc\x74\x0e\x48\x89\xd1\x48\x83\xe1\xfd\xf6\xc2\x02\x48\x0f\x45\xd1\x41\x83\xf8\x01\x0f\x94\xc1\x83\x7c\x24\x18\x3f\x75\x0d\x49\x89\xd0\x49\x83\xe0\xfb\x84\xc9\x49\x0f\x45\xd0\x83\x7c\x24\x18\x38\x75\x0d\x49\x89\xd0\x49\x83\xe0\xf7\x84\xc9\x49\x0f\x45\xd0\x48\x89\xd1\x48\x83\xe1\xfc\x45\x84\xff\x48\x0f\x45\xd1\x49\x83\xf9\x3f\x77\x10\x49\xc7\xc0\xfe\xff\xff\xff\x44\x89\xc9\x49\xd3\xc0\x4c\x21\xc0\x4c\x8b\x7c\x24\x08\x48\x0b\x44\x24\x30\x41\x83\xf6\x01\x4d\x89\xe9\x45\x89\xf4\x41\xbe\xff\x00\x00\x00\x49\x0f\xc9\x4c\x89\xf9\x49\x0f\xcf\x4c\x09\xe9\x4c\x09\xd9\x48\x09\xd9\x48\x09\xf9\x48\x09\xf1\x48\x31\xc8\x48\x89\x4c\x24\x10\x4c\x89\xd9\x48\x0f\xc9\x49\x89\xc2\x81\xfd\xff\x00\x00\x00\x48\x89\x4c\x24\x18\x48\x89\xd9\x48\x89\xf0\x48\x0f\xc9\x4d\x89\xd0\x48\x0f\xc8\x48\x89\x4c\x24\x20\x48\x89\xf9\x49\x0f\xc8\x48\x0f\xc9\x48\x89\x4c\x24\x28\x74\x28\x8d\x4d\x07\x85\xed\x41\xbe\x07\x00\x00\x00\x0f\x49\xcd\xc1\xf9\x03\x41\x29\xce\x89\xe9\xc1\xf9\x1f\xc1\xe9\x1d\x01\xcd\x83\xe5\x07\x29\xcd\x46\x8d\x74\xf5\x00\x48\x89\xd1\x83\xe1\x01\x48\x83\xf9\x01\x19\xed\xf7\xd9\x83\xe5\xfc\x83\xe1\x04\x83\xc5\x0c\xf6\xc2\x02\x0f\x45\xcd\x89\xcd\x83\xcd\x01\xf6\xc2\x04\x0f\x45\xcd\x89\xcd\x83\xcd\x02\x83\xe2\x08\x0f\x45\xcd\x45\x84\xe4\x0f\x84\xc0\x04\x00\x00\x48\x63\xd9\x48\x89\x5c\x24\x10\x48\x8b\x2c\x24\x41\xba\x40\x00\x00\x00\xbb\x07\x00\x00\x00\x41\xbb\x01\x00\x00\x00\x44\x88\x64\x24\x08\x4d\x8d\x62\xf8\x31\xd2\x4c\x89\xe1\xeb\x79\x0f\x1f\x40\x00\x4d\x89\xdd\x49\xd3\xe5\x49\x85\xc5\x0f\x84\xd1\x01\x00\x00\x85\xd2\x0f\x84\xb2\x06\x00\x00\xbe\x01\x00\x00\x00\x83\xc2\x30\x4d\x85\xc5\x48\x8d\x7d\x01\x88\x55\x00\x0f\x95\xc2\x83\xfe\x04\x0f\x84\x31\x03\x00\x00\x0f\x8e\xef\x02\x00\x00\x83\xfe\x05\x0f\x84\x09\x03\x00\x00\x83\xfe\x06\x0f\x85\xe7\x02\x00\x00\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x50\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x8d\x6f\x01\x88\x17\x31\xd2\x48\x83\xc1\x01\x4c\x39\xd1\x0f\x84\x86\x01\x00\x00\x48\x83\xf9\x3f\x76\x85\x83\xc2\x01\xeb\xe8\x83\xea\x08\x83\xfa\xf8\x0f\x85\x1a\xf6\xff\xff\x0f\xb6\x07\x3c\x62\x0f\x85\x96\xf8\xff\xff\x31\xd2\xc6\x44\x24\x08\x00\xe9\x9c\xf8\xff\xff\x0f\x1f\x44\x00\x00\x3c\x6b\x74\x24\x3c\x71\x0f\x85\x3c\xf6\xff\xff\x49\x83\xca\x08\xe9\x89\xf8\xff\xff\x0f\x1f\x00\x49\x83\xca\x02\xe9\x7d\xf8\xff\xff\x0f\x1f\x80\x00\x00\x00\x00\x49\x83\xca\x04\xe9\x6d\xf8\xff\xff\x83\xf8\x03\x0f\x84\x30\x05\x00\x00\x0f\x8e\x92\x04\x00\x00\x83\xf8\x05\x0f\x84\x19\x05\x00\x00\x0f\x8c\x0b\x05\x00\x00\x41\x83\xf8\x06\x48\x89\xd8\x0f\x85\xec\xf5\xff\xff\x0f\xb6\x74\x24\x08\x0f\xb6\x4c\x24\x18\x48\x8d\x7c\x24\x40\xc7\x84\x24\xb8\x01\x00\x00\xff\x00\x00\x00\x48\xc7\xc2\xfe\xff\xff\xff\x40\x88\xb4\x24\xc8\x01\x00\x00\xff\xb4\x24\xc8\x01\x00\x00\x48\xd3\xc2\x41\x52\x48\x21\xc2\x44\x89\xc6\x4c\x89\x54\x24\x40\xff\xb4\x24\xc8\x01\x00\x00\x41\x53\x53\x55\x41\x54\x41\x55\x41\x56\x41\x57\xe8\x04\xf3\xff\xff\x48\x8b\x94\x24\xd8\x00\x00\x00\x48\x8b\x84\x24\xc8\x00\x00\x00\x4c\x8b\xbc\x24\x90\x00\x00\x00\x4c\x8b\xb4\x24\x98\x00\x00\x00\x4c\x8b\xac\x24\xa0\x00\x00\x00\x4c\x8b\xa4\x24\xa8\x00\x00\x00\x48\x89\x84\x24\x08\x02\x00\x00\x48\x89\x94\x24\x18\x02\x00\x00\x48\x8b\xac\x24\xb0\x00\x00\x00\x48\x8b\x9c\x24\xb8\x00\x00\x00\x4c\x8b\x9c\x24\xc0\x00\x00\x00\x48\x8b\xb4\x24\xd0\x00\x00\x00\x88\x54\x24\x58\x48\x83\xc4\x50\x4c\x8b\x54\x24\x30\xe9\xc9\xfa\xff\xff\x81\x4c\x24\x18\x80\x00\x00\x00\xe9\x76\xf9\xff\xff\x0f\x1f\x44\x00\x00\x4d\x85\xcd\x0f\x84\x2a\x01\x00\x00\x85\xd2\x0f\x84\x9e\x01\x00\x00\xbe\x02\x00\x00\x00\xe9\x21\xfe\xff\xff\x85\xd2\x48\x89\xe9\x74\x0a\x83\xc2\x30\x48\x83\xc1\x01\x88\x55\x00\x85\xdb\x0f\x84\xc8\x04\x00\x00\x48\x8d\x69\x01\xc6\x01\x2f\x83\xeb\x01\x4d\x89\xe2\x83\xfb\xff\x0f\x85\xc7\xfd\xff\xff\x44\x0f\xb6\x64\x24\x08\x48\x89\x2c\x24\xc6\x45\x00\x20\xc6\x45\x02\x20\x41\x80\xfc\x01\x19\xc0\x83\xe0\xeb\x83\xc0\x77\x88\x45\x01\x48\x89\xe8\x48\x83\xc0\x03\xf6\x44\x24\x10\x01\x74\x0b\x48\x89\xe8\xc6\x45\x03\x4b\x48\x83\xc0\x04\xf6\x44\x24\x10\x02\x74\x07\xc6\x00\x51\x48\x83\xc0\x01\xf6\x44\x24\x10\x04\x74\x07\xc6\x00\x6b\x48\x83\xc0\x01\xf6\x44\x24\x10\x08\x0f\x84\x42\x03\x00\x00\x48\x8d\x50\x01\xc6\x00\x71\x41\x81\xfe\xff\x00\x00\x00\xc6\x02\x20\x48\x8d\x4a\x02\xb8\x2d\x00\x00\x00\x74\x2d\x44\x89\xf1\xc1\xf9\x1f\xc1\xe9\x1d\x41\x8d\x04\x0e\x83\xe0\x07\x29\xc8\x41\x8d\x4e\x07\x83\xc0\x61\x45\x85\xf6\x41\x0f\x49\xce\xc1\xf9\x03\x83\xc1\x31\x88\x4a\x02\x48\x8d\x4a\x03\x88\x42\x01\xc6\x01\x20\x48\x8b\x84\x24\xd8\x01\x00\x00\x64\x48\x33\x04\x25\x28\x00\x00\x00\xc6\x41\x01\x30\xc6\x41\x02\x20\xc6\x41\x03\x31\xc6\x41\x04\x00\x0f\x85\xd6\x03\x00\x00\x48\x81\xc4\xe8\x01\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x4d\x85\xfd\x0f\x84\x56\x01\x00\x00\x85\xd2\x74\x56\xbe\x03\x00\x00\x00\xe9\xf2\xfc\xff\xff\x83\xfe\x02\x74\x69\x83\xfe\x03\x74\x4b\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x52\xe9\x1c\xfd\xff\xff\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x4b\xe9\x03\xfd\xff\xff\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x51\xe9\xea\xfc\xff\xff\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x42\xe9\xd1\xfc\xff\xff\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\x80\xfa\x01\x19\xd2\x83\xe2\x20\x83\xc2\x4e\xe9\xb8\xfc\xff\xff\x8b\x7c\x24\x28\x83\xff\x03\x0f\x84\xc6\x02\x00\x00\x0f\x8e\xee\x01\x00\x00\x83\xff\x05\x0f\x84\x7e\x02\x00\x00\x0f\x8c\x70\x02\x00\x00\x83\xff\x06\x48\x89\xda\x0f\x85\x1a\xf3\xff\xff\x4c\x63\x4c\x24\x10\x48\x63\x7c\x24\x18\x49\x83\xf9\x3f\x48\x89\x7c\x24\x30\x77\x10\x48\xc7\xc7\xfe\xff\xff\xff\x44\x89\xc9\x48\xd3\xc7\x48\x21\xfb\x0f\xb6\x4c\x24\x30\x89\x84\x24\xb8\x01\x00\x00\xbf\x01\x00\x00\x00\x0f\xb6\x44\x24\x08\x4c\x89\x54\x24\x38\x48\xd3\xe7\x48\x89\xf9\x48\x89\x7c\x24\x30\x88\x84\x24\xc8\x01\x00\x00\x48\x8d\x7c\x24\x40\x48\x09\xca\xff\xb4\x24\xc8\x01\x00\x00\x56\xff\xb4\x24\xc8\x01\x00\x00\x41\x53\x53\x55\x41\x54\x41\x55\x41\x56\x41\x57\x8b\x74\x24\x78\xe9\xf6\xf8\xff\xff\x48\x83\xe6\xfe\x48\x83\xe0\xfe\x48\x83\xe2\xfd\x48\x83\xce\x08\x48\x83\xc8\x08\xbd\xff\x00\x00\x00\xe9\xf1\xf9\xff\xff\x4c\x85\x6c\x24\x18\x0f\x84\x68\x01\x00\x00\x85\xd2\x0f\x84\xd8\xfe\xff\xff\xbe\x04\x00\x00\x00\xe9\x8d\xfb\xff\xff\x4c\x8b\x44\x24\x10\x4d\x31\xd0\x41\x81\xfe\xff\x00\x00\x00\x74\x2d\x44\x89\xf2\x41\xb9\x07\x00\x00\x00\xc1\xfa\x1f\xc1\xea\x1d\x41\x8d\x04\x16\x83\xe0\x07\x29\xd0\x41\x8d\x56\x07\x45\x85\xf6\x41\x0f\x49\xd6\xc1\xfa\x03\x41\x29\xd1\x46\x8d\x34\xc8\x89\xc8\x48\x89\x7c\x24\x28\x48\x89\x5c\x24\x20\x83\xe0\x01\x4c\x89\x5c\x24\x18\x4c\x8b\x7c\x24\x08\x83\xf8\x01\x4d\x89\xe9\x19\xd2\xf7\xd8\x83\xe2\xfc\x83\xe0\x04\x83\xc2\x0c\xf6\xc1\x02\x0f\x45\xc2\x89\xc2\x83\xca\x01\xf6\xc1\x04\x0f\x45\xc2\x89\xc2\x83\xca\x02\x83\xe1\x08\x0f\x45\xc2\x48\x98\x48\x89\x44\x24\x10\x48\x89\xf0\xe9\xb3\xfa\xff\xff\x39\x4c\x24\x18\x0f\x84\x1c\x01\x00\x00\x44\x8b\x54\x24\x10\x8b\x6c\x24\x18\x44\x89\xd1\xc1\xfd\x03\x83\xc1\x07\x45\x85\xd2\x41\x0f\x49\xca\xc1\xf9\x03\x29\xcd\x89\xe9\x41\x8d\x6a\x08\x83\xf9\x02\xb9\xff\x00\x00\x00\x0f\x45\xe9\x45\x31\xff\xe9\xfe\xf8\xff\xff\x81\x4c\x24\x18\xc0\x00\x00\x00\x3c\x42\x0f\x84\xdc\xf5\xff\xff\xe9\x76\xf1\xff\xff\x83\xf8\x01\x0f\x84\x97\x00\x00\x00\x41\x83\xf8\x02\x4c\x89\xf0\x0f\x84\x74\xfb\xff\xff\x0f\x0b\x83\xff\x01\x0f\x84\xe8\x00\x00\x00\x83\xff\x02\x4c\x89\xf2\x0f\x84\x2a\xf7\xff\xff\x0f\x0b\x83\xff\x01\x0f\x84\xc1\x00\x00\x00\x83\xff\x02\x4c\x89\xf2\x0f\x84\x18\xfe\xff\xff\x0f\x0b\x81\x4c\x24\x18\x00\x01\x00\x00\xe9\x84\xf5\xff\xff\x48\x83\x7c\x24\x10\x00\x0f\x85\xd7\x00\x00\x00\x48\x8d\x50\x01\xc6\x00\x2d\xe9\xad\xfc\xff\xff\x4c\x85\x6c\x24\x20\x0f\x84\x9b\x00\x00\x00\x85\xd2\x0f\x84\x4c\xfd\xff\xff\xbe\x05\x00\x00\x00\xe9\x1a\xfa\xff\xff\x4c\x89\xe0\xe9\xfa\xfa\xff\xff\x48\x89\xe8\xe9\xf2\xfa\xff\xff\x4c\x89\xe8\xe9\xea\xfa\xff\xff\x4c\x89\xf8\xe9\xe2\xfa\xff\xff\x4c\x89\xea\xe9\xa7\xf6\xff\xff\x48\x89\xea\xe9\x9f\xf6\xff\xff\x4c\x89\xe2\xe9\x97\xf6\xff\xff\x4c\x89\xe2\xe9\x94\xfd\xff\xff\x48\x89\xea\xe9\x8c\xfd\xff\xff\x8b\x4c\x24\x18\x48\xc7\xc5\xff\xff\xff\xff\x83\xe9\x08\x48\x63\xc9\x48\x83\xf9\x3f\x77\x0a\x48\xc7\xc5\xfe\xff\xff\xff\x48\xd3\xc5\x48\x21\xef\xe9\xbb\xfe\xff\xff\x4c\x89\xfa\xe9\x5b\xfd\xff\xff\x4c\x89\xea\xe9\x53\xfd\xff\xff\x4c\x89\xfa\xe9\x46\xf6\xff\xff\x4c\x85\x6c\x24\x28\x0f\x84\xe5\xf9\xff\xff\x85\xd2\x75\x25\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\xe9\xa5\xf9\xff\xff\x41\x89\xcf\xe9\xae\xf7\xff\xff\x48\x89\xc2\xe9\xda\xfb\xff\xff\x89\xe9\xe9\x83\xf7\xff\xff\xbe\x06\x00\x00\x00\xe9\x53\xf9\xff\xff\x4d\x85\xc5\x48\x89\xef\x0f\x95\xc2\xe9\x5d\xfc\xff\xff\xe8\x00\x00\x00\x00\x48\x89\xcd\xe9\x37\xfb\xff\xff' 6 | offset = 512 7 | libc = CDLL('libc.so.6') 8 | 9 | src_ptr = c_char_p(shellcode) 10 | size = len(shellcode) 11 | 12 | code_ptr = libc.valloc(size) 13 | code_ptr = c_void_p(code_ptr) 14 | 15 | memmove(code_ptr, src_ptr, size) 16 | err = libc.mprotect(code_ptr, size, 0x7) 17 | if 0 != err: 18 | raise Exception("mprotect: " + str(err)) 19 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 20 | fen_buf = c_char_p(fen) 21 | move_buf = c_char_p(move) 22 | result_buf = create_string_buffer(300) 23 | 24 | SHELLCODE_T = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p) 25 | 26 | fptr = cast(main_ptr, SHELLCODE_T) 27 | result = fptr(fen, move_buf, result_buf) 28 | libc.free(code_ptr) 29 | return result_buf.raw 30 | return execute() 31 | $$ language plpythonu; 32 | -------------------------------------------------------------------------------- /sql/create-perft.sql: -------------------------------------------------------------------------------- 1 | create or replace function pf_perft (depth int) returns int stable as $$ 2 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE, c_uint64) 3 | 4 | def execute(): 5 | shellcode = b'\x83\xfe\x03\x48\x89\xf8\x74\x2d\x7f\x11\x83\xfe\x01\x74\x1f\x83\xfe\x02\x75\x44\x48\x89\x54\x24\x10\xeb\x2d\x83\xfe\x05\x74\x23\x7c\x1a\x83\xfe\x06\x75\x31\x48\x89\x54\x24\x30\xeb\x1a\x48\x89\x54\x24\x08\xeb\x13\x48\x89\x54\x24\x18\xeb\x0c\x48\x89\x54\x24\x20\xeb\x05\x48\x89\x54\x24\x28\x48\x89\xc7\x48\x8d\x74\x24\x08\xb9\x12\x00\x00\x00\xf3\xa5\xc3\x0f\x0b\x41\x57\x41\x56\x49\x89\xf8\x41\x55\x41\x54\x55\x53\x4c\x8b\x74\x24\x38\x4c\x8b\x7c\x24\x40\x4c\x8b\x6c\x24\x48\x4c\x8b\x64\x24\x50\x48\x8b\x54\x24\x58\x48\x8b\x4c\x24\x60\x4c\x89\xf5\x4d\x09\xfe\x8b\x44\x24\x70\x4d\x89\xeb\x4d\x09\xf5\x4d\x89\xe2\x4d\x09\xec\x49\x89\xd1\x48\x89\xcf\x4c\x09\xe2\x4c\x89\xfb\x48\x8b\x74\x24\x78\x48\x09\xd1\x48\x33\x4c\x24\x68\x3d\xff\x00\x00\x00\x48\x0f\xcd\x48\x0f\xcb\x49\x0f\xcb\x49\x0f\xca\x49\x0f\xc9\x48\x0f\xcf\xba\xff\x00\x00\x00\x48\x0f\xc9\x74\x17\x41\xbc\x08\x00\x00\x00\x99\x41\xf7\xfc\x41\xbc\x07\x00\x00\x00\x41\x29\xc4\x42\x8d\x14\xe2\x48\x89\xf0\x48\x89\x7c\x24\x60\x48\x89\x4c\x24\x68\x83\xe0\x01\x48\x89\x6c\x24\x38\x48\x89\x5c\x24\x40\xf7\xd8\x4c\x89\x5c\x24\x48\x4c\x89\x54\x24\x50\x83\xe0\x04\x4c\x89\x4c\x24\x58\x89\x54\x24\x70\x41\x89\xc4\xb9\x12\x00\x00\x00\x4c\x89\xc7\x41\x83\xcc\x08\x40\xf6\xc6\x02\x41\x0f\x45\xc4\x41\x89\xc4\x41\x83\xcc\x01\x40\xf6\xc6\x04\x41\x0f\x45\xc4\x41\x89\xc4\x41\x83\xcc\x02\x40\x80\xe6\x08\x48\x8d\x74\x24\x38\x41\x0f\x45\xc4\x48\x98\x48\x89\x44\x24\x78\x4c\x89\xc0\xf3\xa5\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x31\xc0\x48\x83\xfe\x3f\x77\x11\xb8\x01\x00\x00\x00\x40\x88\xf1\x48\xd3\xe0\x48\x85\xf8\x0f\x95\xc0\xc3\x4d\x85\xc9\x41\x0f\x94\xc1\x48\x83\x7c\x24\x08\x00\x0f\x94\xc0\x44\x21\xc8\x4d\x85\xc0\x41\x0f\x94\xc0\x44\x21\xc0\x48\x85\xc9\x0f\x94\xc1\x21\xc8\x48\x85\xd2\x0f\x94\xc2\x21\xd0\x48\x09\xf7\x0f\x94\xc2\x21\xd0\xc3\x53\x4c\x63\x54\x24\x10\x48\x89\xf3\x49\x89\xcb\x4c\x89\xd6\xe8\x9c\xff\xff\xff\x84\xc0\xb9\x01\x00\x00\x00\x75\x64\x4c\x89\xd6\x48\x89\xdf\xe8\x88\xff\xff\xff\x84\xc0\xb9\x02\x00\x00\x00\x75\x50\x4c\x89\xd6\x48\x89\xd7\xe8\x74\xff\xff\xff\x84\xc0\xb9\x03\x00\x00\x00\x75\x3c\x4c\x89\xd6\x4c\x89\xdf\xe8\x60\xff\xff\xff\x84\xc0\xb9\x04\x00\x00\x00\x75\x28\x4c\x89\xd6\x4c\x89\xc7\xe8\x4c\xff\xff\xff\x84\xc0\xb9\x05\x00\x00\x00\x75\x14\x4c\x89\xd6\x4c\x89\xcf\xe8\x38\xff\xff\xff\x3c\x01\x19\xc9\xf7\xd1\x83\xe1\x06\x89\xc8\x5b\xc3\x44\x8b\x54\x24\x08\x41\x83\xfa\x03\x74\x30\x7f\x0f\x41\x83\xfa\x01\x74\x24\x48\x89\xf0\x41\x83\xfa\x02\xeb\x0f\x41\x83\xfa\x05\x74\x11\x7c\x0b\x4c\x89\xc8\x41\x83\xfa\x06\x74\x11\x0f\x0b\x48\x89\xc8\xc3\x4c\x89\xc0\xc3\x48\x89\xf8\xc3\x48\x89\xd0\xc3\x48\x85\xff\x75\x38\x48\x85\xf6\xb8\x02\x00\x00\x00\x75\x33\x48\x85\xd2\xb8\x03\x00\x00\x00\x75\x29\x48\x85\xc9\xb8\x04\x00\x00\x00\x75\x1f\x4d\x85\xc0\xb8\x05\x00\x00\x00\x75\x15\x4d\x85\xc9\xb8\x06\x00\x00\x00\x75\x0b\xb8\xff\x00\x00\x00\xc3\xb8\x01\x00\x00\x00\x50\xe8\x79\xff\xff\xff\x5a\x48\x0f\xbc\xc0\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x55\x53\x48\x83\xec\x38\x4c\x8b\xa4\x24\xa8\x00\x00\x00\x4c\x8b\x94\x24\x90\x00\x00\x00\x4c\x8b\x9c\x24\x98\x00\x00\x00\x48\x8b\x5c\x24\x78\x4c\x8b\xac\x24\x80\x00\x00\x00\x4c\x8b\xb4\x24\x88\x00\x00\x00\x4c\x8b\xbc\x24\xa0\x00\x00\x00\x48\x89\x3c\x24\x48\x89\x74\x24\x10\x48\x89\x54\x24\x18\x48\x89\xdf\x48\x89\x4c\x24\x20\x4c\x89\x44\x24\x28\x4c\x89\xd1\x4c\x89\x4c\x24\x30\x41\x54\x4d\x89\xf9\x4d\x89\xd8\x4c\x89\xf2\x4c\x89\xee\xe8\x3f\xfe\xff\xff\x59\x84\xc0\x48\x8d\x44\x24\x78\x48\x89\x44\x24\x08\x74\x0e\xb9\x12\x00\x00\x00\x48\x8b\x3c\x24\x48\x89\xc6\xeb\x7e\x4d\x89\xf9\x4d\x89\xd8\x4c\x89\xd1\x4c\x89\xf2\x4c\x89\xee\x48\x89\xdf\xe8\x05\xff\xff\xff\x48\x8b\xac\x24\xb8\x00\x00\x00\x50\x41\x89\xc7\x4c\x8b\x4c\x24\x78\x4c\x8b\x44\x24\x38\x48\x8b\x4c\x24\x30\x48\x8b\x54\x24\x28\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\x12\xfe\xff\xff\x83\xf8\x06\x5a\x75\x1c\x44\x89\xf8\xb9\x08\x00\x00\x00\x99\xf7\xf9\x83\xf8\x06\x75\x0c\x4d\x85\xe4\xb8\x04\x00\x00\x00\x48\x0f\x45\xe8\x48\x8b\x3c\x24\x48\x8b\x74\x24\x08\xb9\x12\x00\x00\x00\x48\x89\xac\x24\xb8\x00\x00\x00\xf3\xa5\x48\x8b\x04\x24\x48\x83\xc4\x38\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\xe8\x84\xfe\xff\xff\x48\x0f\xbc\x54\x24\x08\x8b\x4c\x24\x10\x89\xc0\xc1\xe1\x06\x09\xca\x48\xc1\xe2\x20\x48\x09\xd0\xc3\x83\xfe\x03\x53\x74\x37\x7f\x12\x83\xfe\x01\x74\x37\x7f\x23\x85\xf6\xba\x01\x00\x00\x00\x74\x2f\xeb\x31\x83\xfe\x05\x74\x2e\x7c\x31\x83\xfe\x06\x74\x10\x83\xca\xff\x83\xfe\x07\x89\xd0\x74\x2c\xeb\x19\x31\xd2\xeb\x21\xba\x01\x00\x00\x00\xeb\x02\x31\xd2\x83\xc8\xff\xeb\x18\x83\xca\xff\x31\xc0\xeb\x11\x0f\x0b\x83\xca\xff\xeb\x05\xba\x01\x00\x00\x00\xb8\x01\x00\x00\x00\x48\x63\xff\x45\x31\xc0\x48\x83\xff\x3f\x77\x0c\x41\xb8\x01\x00\x00\x00\x40\x88\xf9\x49\xd3\xe0\x8d\x34\xc5\x00\x00\x00\x00\x49\xba\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x49\xbb\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x41\x89\xf1\x41\xf7\xd9\x44\x88\xc9\x4c\x89\xc3\x4c\x89\xc0\x48\xd3\xeb\x40\x88\xf1\x48\xd3\xe0\x85\xf6\x48\x0f\x48\xc3\x83\xfa\xff\x75\x08\x48\xd1\xe8\x4c\x21\xd8\xeb\x12\x88\xd1\x48\xd3\xe0\x48\x89\xc1\x4c\x21\xd1\x83\xfa\x01\x48\x0f\x44\xc1\x4c\x09\xc0\x49\x39\xc0\x74\x05\x49\x89\xc0\xeb\xbc\x31\xd2\x48\x83\xff\x3f\x77\x0b\xba\x01\x00\x00\x00\x40\x88\xf9\x48\xd3\xe2\x48\xf7\xd2\x48\x21\xd0\x5b\xc3\x4d\x09\xc1\x41\x54\x55\x53\x4c\x89\xcb\x8b\x6c\x24\x30\x48\x09\xcb\x48\x09\xd3\x48\x09\xde\x48\x09\xfe\x8b\x7c\x24\x28\x48\x89\xf3\x89\xee\xe8\xe4\xfe\xff\xff\x48\x21\xc3\x49\x89\xc4\x74\x6f\x83\xfd\x07\x77\x2a\xb8\x01\x00\x00\x00\x40\x88\xe9\x48\xd3\xe0\xa8\xca\x75\x0a\x48\x0f\xbc\xdb\xa8\x35\x75\x15\xeb\x11\x48\x0f\xbd\xf3\xbb\x3f\x00\x00\x00\x48\x83\xf6\x3f\x29\xf3\xeb\x02\x0f\x0b\x89\xee\x89\xdf\xe8\xa2\xfe\xff\xff\x48\x8b\x7c\x24\x20\x4c\x89\xe2\x48\x63\xf3\x48\x31\xc2\xe8\xe6\xfb\xff\xff\x84\xc0\x75\x0f\xb8\x01\x00\x00\x00\x88\xd9\x48\xd3\xe0\x48\x09\xd0\xeb\x0f\x48\xc7\xc0\xfe\xff\xff\xff\x88\xd9\x48\xd3\xc0\x48\x21\xd0\x5b\x5d\x41\x5c\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x4d\x89\xcd\x55\x53\x48\x89\xcd\x48\x89\xd3\x4d\x89\xc4\x48\x83\xec\x18\x4c\x8b\x74\x24\x50\x44\x8b\x7c\x24\x58\x48\x89\x3c\x24\x48\x89\x74\x24\x08\x6a\x02\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\x1a\xff\xff\xff\x48\x83\xc4\x18\x48\x89\x44\x24\x10\x4d\x89\xe9\x6a\x01\x41\x57\x4d\x89\xe0\x41\x56\x48\x8b\x74\x24\x20\x48\x89\xe9\x48\x8b\x7c\x24\x18\x48\x89\xda\xe8\xf0\xfe\xff\xff\x48\x83\xc4\x18\x48\x0b\x44\x24\x10\x4d\x89\xe9\x4d\x89\xe0\x48\x89\xe9\x48\x89\xda\x48\x89\x44\x24\x10\x6a\x00\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\xc1\xfe\xff\xff\x48\x83\xc4\x18\x48\x0b\x44\x24\x10\x4d\x89\xe9\x4d\x89\xe0\x48\x89\xe9\x48\x89\xda\x48\x89\x44\x24\x10\x6a\x03\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\x92\xfe\xff\xff\x48\x0b\x44\x24\x28\x48\x83\xc4\x30\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x4d\x89\xcd\x55\x53\x48\x89\xcd\x48\x89\xd3\x4d\x89\xc4\x48\x83\xec\x18\x4c\x8b\x74\x24\x50\x44\x8b\x7c\x24\x58\x48\x89\x3c\x24\x48\x89\x74\x24\x08\x6a\x04\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\x3c\xfe\xff\xff\x48\x83\xc4\x18\x48\x89\x44\x24\x10\x4d\x89\xe9\x6a\x05\x41\x57\x4d\x89\xe0\x41\x56\x48\x8b\x74\x24\x20\x48\x89\xe9\x48\x8b\x7c\x24\x18\x48\x89\xda\xe8\x12\xfe\xff\xff\x48\x83\xc4\x18\x48\x0b\x44\x24\x10\x4d\x89\xe9\x4d\x89\xe0\x48\x89\xe9\x48\x89\xda\x48\x89\x44\x24\x10\x6a\x06\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\xe3\xfd\xff\xff\x48\x83\xc4\x18\x48\x0b\x44\x24\x10\x4d\x89\xe9\x4d\x89\xe0\x48\x89\xe9\x48\x89\xda\x48\x89\x44\x24\x10\x6a\x07\x41\x57\x41\x56\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x18\xe8\xb4\xfd\xff\xff\x48\x0b\x44\x24\x28\x48\x83\xc4\x30\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\x4d\x89\xce\x41\x55\x41\x54\x4d\x89\xc5\x55\x53\x49\x89\xcc\x48\x89\xfb\x48\x81\xec\x88\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x44\x24\x78\x31\xc0\x48\x8b\x84\x24\xe8\x00\x00\x00\x4c\x8b\x94\x24\x00\x01\x00\x00\x4c\x8b\x9c\x24\x08\x01\x00\x00\x48\x8b\xac\x24\xe0\x00\x00\x00\x4c\x8b\xbc\x24\xf8\x00\x00\x00\x48\x89\x34\x24\x48\x89\x44\x24\x10\x48\x8b\x84\x24\xf0\x00\x00\x00\x4d\x89\xd0\x48\x89\x54\x24\x08\x4d\x89\xd9\x48\x89\xef\x4c\x89\xf9\x48\x89\x44\x24\x18\xff\xb4\x24\x10\x01\x00\x00\x48\x8b\x54\x24\x20\x48\x8b\x74\x24\x18\xe8\x8b\xf9\xff\xff\x84\xc0\x5a\x74\x4b\x48\xc7\x43\x30\x00\x00\x00\x00\x48\xc7\x03\x00\x00\x00\x00\x48\xc7\x43\x08\x00\x00\x00\x00\x48\xc7\x43\x10\x00\x00\x00\x00\x48\xc7\x43\x18\x00\x00\x00\x00\x48\xc7\x43\x20\x00\x00\x00\x00\x48\xc7\x43\x28\x00\x00\x00\x00\xc7\x43\x38\xff\x00\x00\x00\x48\xc7\x43\x40\x00\x00\x00\x00\xe9\x48\x06\x00\x00\x48\x8b\x54\x24\x18\x48\x8b\x74\x24\x10\x4d\x89\xd0\x4d\x89\xd9\x48\x89\xef\x4c\x89\xf9\xe8\x1a\xfa\xff\xff\x50\x4c\x8b\x8c\x24\xc8\x00\x00\x00\x4d\x89\xf0\x48\x8b\x74\x24\x10\x48\x8b\x7c\x24\x08\x4c\x89\xe9\x4c\x89\xe2\x89\xc5\xe8\x33\xf9\xff\xff\x83\xf8\x03\x41\x5a\x0f\x84\x1b\x02\x00\x00\x7f\x0f\x83\xf8\x01\x74\x27\x83\xf8\x02\x74\x4f\xe9\x76\x05\x00\x00\x83\xf8\x05\x0f\x84\x8e\x02\x00\x00\x0f\x8c\x2c\x02\x00\x00\x83\xf8\x06\x0f\x84\x1d\x04\x00\x00\xe9\x59\x05\x00\x00\x55\xff\xb4\x24\xd0\x00\x00\x00\x4d\x89\xf0\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x48\x8b\x74\x24\x18\x4c\x89\xe9\x48\x8b\x7c\x24\x10\x4c\x89\xe2\xe8\xc3\xfc\xff\xff\xe9\xe8\x01\x00\x00\x8d\x75\x10\xb9\xff\x00\x00\x00\x83\xfe\x3f\x77\x0a\x8d\x45\x0f\x40\xf6\xc6\x07\x0f\x45\xc8\x48\x63\xc9\x31\xd2\x48\x83\xf9\x3f\x77\x08\xba\x01\x00\x00\x00\x48\xd3\xe2\x49\xb8\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\xb9\xff\x00\x00\x00\x4c\x21\xc2\x83\xfe\x3f\x77\x0c\x83\xe6\x07\x8d\x45\x11\x83\xfe\x07\x0f\x45\xc8\x48\x63\xc9\x31\xf6\x48\x83\xf9\x3f\x77\x08\xbe\x01\x00\x00\x00\x48\xd3\xe6\x49\xb8\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xb9\xff\x00\x00\x00\x4c\x21\xc6\x48\x09\xd6\x49\x89\xf0\x8d\x75\xf0\x83\xfe\x3f\x77\x0a\x8d\x45\xef\x40\xf6\xc6\x07\x0f\x45\xc8\x48\x63\xc9\x31\xff\x48\x83\xf9\x3f\x77\x08\xbf\x01\x00\x00\x00\x48\xd3\xe7\x48\xba\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\xb9\xff\x00\x00\x00\x48\x21\xfa\x4c\x09\xc2\x83\xfe\x3f\x77\x0c\x83\xe6\x07\x8d\x45\xf1\x83\xfe\x07\x0f\x45\xc8\x48\x63\xc9\x31\xc0\x48\x83\xf9\x3f\x77\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\xb9\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x48\x21\xc8\x48\x09\xc2\x83\xfd\x3f\x77\x39\x89\xe8\x83\xe0\x07\x83\xf8\x07\x74\x2f\x8d\x45\x01\x83\xf8\x40\x74\x27\x83\xe0\x07\x83\xf8\x07\x74\x1f\x8d\x7d\x02\x83\xff\x40\x74\x1c\x8d\x4d\x0a\x31\xc0\x83\xf9\x3f\x7f\x14\xbe\x01\x00\x00\x00\x48\x89\xf0\x48\xd3\xe0\xeb\x07\xbf\xff\x00\x00\x00\x31\xc0\x48\x09\xd0\x8d\x57\xf8\x83\xff\x3f\xb9\xff\x00\x00\x00\x0f\x4e\xca\x31\xf6\x48\x63\xc9\x48\x83\xf9\x3f\x77\x08\xbe\x01\x00\x00\x00\x48\xd3\xe6\x48\x09\xf0\x83\xfd\x3f\x77\x28\x40\xf6\xc5\x07\x74\x22\x8d\x55\xff\x80\xe2\x07\x74\x1a\x8d\x4d\x06\x31\xf6\x8d\x55\xfe\x83\xf9\x3f\x7f\x14\xbf\x01\x00\x00\x00\x48\xd3\xe7\x48\x89\xfe\xeb\x07\xba\xff\x00\x00\x00\x31\xf6\x48\x09\xc6\x8d\x42\xf8\x83\xfa\x3f\xb9\xff\x00\x00\x00\x0f\x4e\xc8\x31\xc0\x48\x63\xc9\x48\x83\xf9\x3f\x77\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x4c\x8b\xbc\x24\xc8\x00\x00\x00\x48\x09\xf0\x49\xf7\xd7\x4c\x21\xf8\xe9\x6e\x03\x00\x00\x55\xff\xb4\x24\xd0\x00\x00\x00\x4d\x89\xf0\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x48\x8b\x74\x24\x18\x4c\x89\xe9\x48\x8b\x7c\x24\x10\x4c\x89\xe2\xe8\xb4\xfb\xff\xff\x41\x58\x41\x59\xe9\x3d\x03\x00\x00\x55\xff\xb4\x24\xd0\x00\x00\x00\x4d\x89\xf0\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x48\x8b\x74\x24\x18\x4c\x89\xe9\x48\x8b\x7c\x24\x10\x4c\x89\xe2\xe8\x83\xfb\xff\xff\x5a\x59\x55\xff\xb4\x24\xd0\x00\x00\x00\x4d\x89\xf0\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x48\x8b\x74\x24\x18\x4c\x89\xe9\x48\x8b\x7c\x24\x10\x4c\x89\xe2\x49\x89\xc7\xe8\x78\xfa\xff\xff\x5e\x5f\xe9\xda\x02\x00\x00\x31\xc0\x83\xfd\x3f\x0f\x87\x45\x03\x00\x00\x89\xea\x83\xe2\x07\x83\xfa\x07\x74\x10\x8d\x4d\x01\x83\xf9\x40\x74\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x40\xf6\xc5\x07\x0f\x84\x21\x03\x00\x00\x8d\x4d\xff\xba\x01\x00\x00\x00\x48\xd3\xe2\x48\x09\xd0\x31\xf6\x83\xfd\x3f\x77\x10\x8d\x4d\x08\x83\xf9\x3f\x7f\x08\xbe\x01\x00\x00\x00\x48\xd3\xe6\x8d\x55\xf8\x48\x09\xf0\xb9\xff\x00\x00\x00\x83\xfd\x3f\x0f\x46\xca\x31\xf6\x48\x63\xc9\x48\x83\xf9\x3f\x77\x0c\x41\xb8\x01\x00\x00\x00\x4c\x89\xc6\x48\xd3\xe6\x48\x09\xc6\x31\xff\x83\xfd\x3f\x77\x1e\x89\xe8\x83\xe0\x07\x83\xf8\x07\x74\x14\x8d\x4d\x09\x83\xf9\x3f\x7f\x0c\x41\xb8\x01\x00\x00\x00\x4c\x89\xc7\x48\xd3\xe7\x48\x09\xfe\x83\xfd\x3f\xb9\xff\x00\x00\x00\x77\x0e\x89\xea\x8d\x45\xf9\x83\xe2\x07\x83\xfa\x07\x0f\x45\xc8\x48\x63\xc9\x45\x31\xff\x48\x83\xf9\x3f\x77\x0b\xbf\x01\x00\x00\x00\x48\xd3\xe7\x49\x89\xff\x48\x89\xf2\x31\xf6\x4c\x09\xfa\x83\xfd\x3f\x77\x19\x40\xf6\xc5\x07\x74\x13\x8d\x4d\x07\x83\xf9\x3f\x7f\x0b\xbf\x01\x00\x00\x00\x48\xd3\xe7\x48\x89\xfe\x48\x09\xd6\x83\xfd\x3f\xb9\xff\x00\x00\x00\x77\x0a\x8d\x45\xf7\x40\x80\xe5\x07\x0f\x45\xc8\x48\x63\xc9\x31\xd2\x48\x83\xf9\x3f\x77\x08\xba\x01\x00\x00\x00\x48\xd3\xe2\x48\x09\xf2\xf6\x84\x24\xd8\x00\x00\x00\x01\x74\x27\x4c\x89\xf0\x48\x0b\x84\x24\xc0\x00\x00\x00\x48\x89\xd1\x48\x83\xc9\x40\x4c\x09\xe8\x4c\x09\xe0\x48\x0b\x44\x24\x08\x48\x0b\x04\x24\xa8\x60\x48\x0f\x44\xd1\xf6\x84\x24\xd8\x00\x00\x00\x02\x74\x27\x4c\x89\xf0\x48\x0b\x84\x24\xc0\x00\x00\x00\x48\x89\xd1\x48\x83\xc9\x04\x4c\x09\xe8\x4c\x09\xe0\x48\x0b\x44\x24\x08\x48\x0b\x04\x24\xa8\x0e\x48\x0f\x44\xd1\x48\x8b\x84\x24\xc8\x00\x00\x00\x48\xf7\xd0\x48\x21\xd0\xe9\x43\x01\x00\x00\x4d\x89\xf0\x4c\x0b\x84\x24\xc0\x00\x00\x00\x44\x8d\x4d\x08\x45\x31\xff\x4d\x63\xd9\x4c\x89\xde\x4d\x09\xe8\x4d\x09\xe0\x4c\x0b\x44\x24\x08\x4c\x0b\x04\x24\x4c\x89\xc7\xe8\x63\xf4\xff\xff\x84\xc0\x75\x4c\x49\x83\xfb\x3f\x77\x0e\xb8\x01\x00\x00\x00\x44\x88\xd9\x48\xd3\xe0\x49\x89\xc7\x89\xe8\xb9\x08\x00\x00\x00\x99\xf7\xf9\xff\xc8\x75\x2a\x8d\x55\x10\x4c\x89\xc7\x48\x63\xd2\x48\x89\xd6\xe8\x2c\xf4\xff\xff\x84\xc0\x75\x15\x31\xc0\x48\x83\xfa\x3f\x77\x0a\xb8\x01\x00\x00\x00\x88\xd1\x48\xd3\xe0\x49\x09\xc7\x89\xe8\xb9\x08\x00\x00\x00\x99\xf7\xf9\x85\xd2\x7e\x32\x41\x83\xf9\x3f\xb9\xff\x00\x00\x00\x77\x0a\x8d\x45\x07\x41\xf6\xc1\x07\x0f\x45\xc8\x48\x63\xc9\x31\xf6\x48\x83\xf9\x3f\x77\x0b\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\x89\xc6\x83\xfa\x07\x74\x33\xeb\x02\x31\xf6\x41\x83\xf9\x3f\xb9\xff\x00\x00\x00\x77\x0e\x41\x83\xe1\x07\x8d\x45\x09\x41\x83\xf9\x07\x0f\x45\xc8\x48\x63\xc9\x31\xc0\x48\x83\xf9\x3f\x77\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\x09\xc6\x4c\x89\xc0\x48\x33\x84\x24\xc8\x00\x00\x00\x48\x21\xf0\x83\xfa\x07\x74\x10\x8d\x4d\x09\x39\x8c\x24\xd0\x00\x00\x00\x74\x12\x85\xd2\x7e\x29\x44\x8d\x55\x07\x44\x39\x94\x24\xd0\x00\x00\x00\x75\x1b\x48\x63\x8c\x24\xd0\x00\x00\x00\x31\xd2\x48\x83\xf9\x3f\x77\x08\xba\x01\x00\x00\x00\x48\xd3\xe2\x48\x09\xd0\x4c\x09\xf8\xeb\x02\x0f\x0b\x48\x89\x84\x24\x10\x01\x00\x00\x4c\x8d\x7c\x24\x20\x48\x83\xec\x48\x48\x8d\xb4\x24\x28\x01\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x4d\x89\xf1\x4c\x89\xe1\x4c\x89\xff\x4d\x89\xe8\xff\xb4\x24\x08\x01\x00\x00\x48\x8b\x74\x24\x50\x48\x8b\x54\x24\x58\xe8\x6c\xf4\xff\xff\x48\x8d\xbc\x24\x30\x01\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xfe\xf3\xa5\x48\x8d\xb4\x24\x30\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x89\xdf\x48\x83\xc4\x50\xf3\xa5\xeb\x07\x31\xd2\xe9\xe3\xfc\xff\xff\x48\x89\xd8\x48\x8b\x5c\x24\x78\x64\x48\x33\x1c\x25\x28\x00\x00\x00\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x88\x00\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x55\x53\x48\x81\xec\xa8\x00\x00\x00\x4c\x8b\x94\x24\x30\x01\x00\x00\x48\x89\x7c\x24\x08\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x98\x00\x00\x00\x31\xc0\x48\x89\x74\x24\x10\x48\x89\x54\x24\x18\x4d\x85\xd2\x48\x89\x4c\x24\x20\x4c\x89\x44\x24\x28\x4c\x89\x4c\x24\x30\x4c\x8b\xb4\x24\x00\x01\x00\x00\x4c\x8b\xac\x24\x08\x01\x00\x00\x4c\x8b\xa4\x24\x10\x01\x00\x00\x48\x8b\xac\x24\x18\x01\x00\x00\x48\x8b\x9c\x24\x20\x01\x00\x00\x4c\x8b\x9c\x24\x28\x01\x00\x00\x4c\x8b\xbc\x24\x40\x01\x00\x00\x0f\x84\xc5\x00\x00\x00\x4d\x85\xff\x74\x09\x49\xff\xcf\x0f\x85\xb7\x00\x00\x00\x49\x8d\x42\xff\x48\xc7\x84\x24\x40\x01\x00\x00\x00\x00\x00\x00\x48\x8d\x5c\x24\x40\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x49\x21\xc2\x4c\x89\x94\x24\x78\x01\x00\x00\x48\x8d\xb4\x24\x48\x01\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xdf\xff\xb4\x24\x28\x01\x00\x00\x48\x8b\x4c\x24\x70\x48\x8b\x74\x24\x60\x4c\x8b\x8c\x24\x80\x00\x00\x00\x4c\x8b\x44\x24\x78\x48\x8b\x54\x24\x68\xe8\x17\xf3\xff\xff\x48\x8d\xbc\x24\x50\x01\x00\x00\x48\x89\xde\xb9\x12\x00\x00\x00\xf3\xa5\x4c\x8b\xb4\x24\x50\x01\x00\x00\x4c\x8b\xac\x24\x58\x01\x00\x00\x4c\x8b\xa4\x24\x60\x01\x00\x00\x48\x8b\xac\x24\x68\x01\x00\x00\x48\x8b\x9c\x24\x70\x01\x00\x00\x4c\x8b\x9c\x24\x78\x01\x00\x00\x4c\x8b\x94\x24\x80\x01\x00\x00\x4c\x8b\xbc\x24\x90\x01\x00\x00\x48\x83\xc4\x50\x48\x8d\x44\x24\x40\x48\x89\x44\x24\x38\x41\x52\x4c\x89\xe2\x4d\x89\xd9\x49\x89\xd8\x48\x89\xe9\x4c\x89\xee\x4c\x89\xf7\xe8\x56\xf1\xff\xff\x4d\x85\xd2\x5a\x0f\x94\xc2\x38\xc2\x77\x13\x4d\x85\xd2\x0f\x84\x65\x01\x00\x00\x84\xc0\x0f\x84\x5d\x01\x00\x00\x0f\x0b\x4d\x85\xf6\x74\x09\x49\x8d\x46\xff\x49\x21\xc6\xeb\x45\x4d\x85\xed\x74\x09\x49\x8d\x45\xff\x49\x21\xc5\xeb\x37\x4d\x85\xe4\x74\x0a\x49\x8d\x44\x24\xff\x49\x21\xc4\xeb\x28\x48\x85\xed\x74\x09\x48\x8d\x45\xff\x48\x21\xc5\xeb\x1a\x48\x85\xdb\x74\x09\x48\x8d\x43\xff\x48\x21\xc3\xeb\x0c\x4d\x85\xdb\x74\x07\x49\x8d\x43\xff\x49\x21\xc3\x4c\x89\xb4\x24\x00\x01\x00\x00\x4c\x89\xac\x24\x08\x01\x00\x00\x48\x83\xec\x50\x4c\x89\xa4\x24\x60\x01\x00\x00\x48\x89\xac\x24\x68\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x89\x9c\x24\x70\x01\x00\x00\x4c\x89\x9c\x24\x78\x01\x00\x00\x4c\x89\x94\x24\x80\x01\x00\x00\x4c\x89\xbc\x24\x90\x01\x00\x00\x48\x8d\xb4\x24\x50\x01\x00\x00\x48\x89\xe7\xf3\xa5\xff\xb4\x24\x48\x01\x00\x00\x8b\x84\x24\x48\x01\x00\x00\x50\xff\xb4\x24\x48\x01\x00\x00\xff\xb4\x24\x48\x01\x00\x00\x48\x8b\x8c\x24\x90\x00\x00\x00\x48\x8b\xb4\x24\x80\x00\x00\x00\x48\x8b\xbc\x24\xa8\x00\x00\x00\x4c\x8b\x8c\x24\xa0\x00\x00\x00\x4c\x8b\x84\x24\x98\x00\x00\x00\x48\x8b\x94\x24\x88\x00\x00\x00\xe8\x20\xf6\xff\xff\x48\x8d\xbc\x24\x70\x01\x00\x00\x48\x8b\xb4\x24\xa8\x00\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x4c\x8b\xb4\x24\x70\x01\x00\x00\x4c\x8b\xac\x24\x78\x01\x00\x00\x4c\x8b\xa4\x24\x80\x01\x00\x00\x48\x8b\xac\x24\x88\x01\x00\x00\x48\x8b\x9c\x24\x90\x01\x00\x00\x4c\x8b\x9c\x24\x98\x01\x00\x00\x4c\x8b\x94\x24\xa0\x01\x00\x00\x4c\x8b\xbc\x24\xb0\x01\x00\x00\x48\x83\xc4\x70\xe9\x6e\xfe\xff\xff\x48\x8b\x94\x24\x98\x00\x00\x00\x64\x48\x33\x14\x25\x28\x00\x00\x00\x4c\x89\xb4\x24\x00\x01\x00\x00\x4c\x89\xac\x24\x08\x01\x00\x00\x48\x8d\xb4\x24\x00\x01\x00\x00\x4c\x89\xa4\x24\x10\x01\x00\x00\x48\x89\xac\x24\x18\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x89\x9c\x24\x20\x01\x00\x00\x4c\x89\x9c\x24\x28\x01\x00\x00\x4c\x89\x94\x24\x30\x01\x00\x00\x4c\x89\xbc\x24\x40\x01\x00\x00\x48\x8b\x7c\x24\x08\x48\x8b\x44\x24\x08\xf3\xa5\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\xa8\x00\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\xb9\x12\x00\x00\x00\x41\x55\x41\x54\x55\x53\x48\x89\xfb\x48\x81\xec\x98\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x88\x00\x00\x00\x31\xc0\x48\x8b\x84\x24\xd0\x00\x00\x00\x48\x8b\xac\x24\x00\x01\x00\x00\x48\x8d\xb4\x24\xd0\x00\x00\x00\x4c\x8b\xa4\x24\xd8\x00\x00\x00\x4c\x8b\xac\x24\xe0\x00\x00\x00\xf3\xa5\x48\x89\x44\x24\x10\x48\x8b\x54\x24\x10\x48\x8d\x74\x24\x30\x4c\x8b\xb4\x24\xe8\x00\x00\x00\x4c\x8b\xbc\x24\xf0\x00\x00\x00\x48\x83\xec\x50\x48\x8b\x84\x24\x48\x01\x00\x00\x4c\x8b\x9c\x24\x60\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x21\xea\x48\x89\x74\x24\x58\x44\x8b\x94\x24\x58\x01\x00\x00\x48\x89\x13\x4c\x89\xe2\x48\x89\xe7\x48\x21\xea\x48\xc7\x43\x40\x00\x00\x00\x00\x48\x89\xde\x48\x89\x53\x08\x4c\x89\xea\x4d\x89\xf9\x48\x21\xea\x4d\x89\xf0\x48\x89\x53\x10\x4c\x89\xf2\x48\x21\xea\x48\x89\x53\x18\x4c\x89\xfa\x48\x21\xea\x48\x89\x53\x20\x48\x89\xc2\x48\x21\xea\x48\x89\x53\x28\x4c\x89\xe2\xf3\xa5\x41\x53\x4c\x89\xe9\x4c\x89\x9c\x24\x80\x00\x00\x00\x41\x52\x44\x89\x94\x24\x84\x00\x00\x00\x55\x50\x48\x8b\xb4\x24\x80\x00\x00\x00\x48\x8b\x7c\x24\x78\x48\x89\x84\x24\x88\x00\x00\x00\xe8\x1e\xf4\xff\xff\x48\x8b\x74\x24\x78\xb9\x12\x00\x00\x00\x48\x89\xdf\xf3\xa5\x48\x83\xc4\x70\x48\x8b\x44\x24\x18\x44\x8b\x54\x24\x24\x4c\x8b\x5c\x24\x28\x48\x83\x7b\x30\x00\x75\x48\x48\x83\xec\x50\xb9\x12\x00\x00\x00\x48\x89\xde\x48\x89\xe7\x4d\x89\xf9\x4d\x89\xf0\xf3\xa5\x41\x53\x41\x52\x4c\x89\xe9\x55\x50\x4c\x89\xe2\x48\x8b\xb4\x24\x80\x00\x00\x00\x48\x8b\x7c\x24\x78\xe8\x14\xfb\xff\xff\x48\x8b\x74\x24\x78\xb9\x12\x00\x00\x00\x48\x89\xdf\xf3\xa5\x48\x83\xc4\x70\x48\x8b\x8c\x24\x88\x00\x00\x00\x64\x48\x33\x0c\x25\x28\x00\x00\x00\x48\x89\xd8\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x98\x00\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\xb9\x12\x00\x00\x00\x41\x55\x41\x54\x55\x53\x48\x81\xec\x28\x01\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x18\x01\x00\x00\x31\xc0\x4c\x8d\x64\x24\x30\x48\x83\xec\x48\x48\x89\xe7\x48\x8d\xb4\x24\xa8\x01\x00\x00\xf3\xa5\x4c\x89\xe7\xe8\x27\xec\xff\xff\x48\x8d\xbc\x24\xa8\x01\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xe6\xf3\xa5\x48\x8d\xbc\x24\xd0\x00\x00\x00\x48\x8d\xb4\x24\xa8\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x8b\x84\x24\xb0\x01\x00\x00\x4c\x8b\xac\x24\xa8\x01\x00\x00\x48\x8b\xac\x24\xd0\x01\x00\x00\x48\x8b\x9c\x24\xd8\x01\x00\x00\x44\x8b\xb4\x24\xe0\x01\x00\x00\x4c\x8b\xbc\x24\xe8\x01\x00\x00\x48\x89\x44\x24\x50\x48\x8b\x84\x24\xb8\x01\x00\x00\xf3\xa5\x4c\x89\xac\x24\xd0\x00\x00\x00\x48\x89\xac\x24\xf8\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x89\x44\x24\x58\x48\x8b\x84\x24\xc0\x01\x00\x00\x48\x89\x9c\x24\x00\x01\x00\x00\x44\x89\xb4\x24\x08\x01\x00\x00\x4c\x89\xbc\x24\x10\x01\x00\x00\x48\x89\x44\x24\x60\x48\x8b\x84\x24\xc8\x01\x00\x00\x48\x89\x44\x24\x68\x48\x8b\x44\x24\x50\x48\x89\x84\x24\xd8\x00\x00\x00\x48\x8b\x44\x24\x58\x48\x89\x84\x24\xe0\x00\x00\x00\x48\x8b\x44\x24\x60\x48\x89\x84\x24\xe8\x00\x00\x00\x48\x8b\x44\x24\x68\x48\x89\x84\x24\xf0\x00\x00\x00\x48\x8d\x84\x24\x18\x01\x00\x00\x56\x48\x8d\xb4\x24\xd8\x00\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xc7\xe8\xf8\xfc\xff\xff\x4c\x8b\x94\x24\x50\x01\x00\x00\x48\x83\xc4\x50\x48\xc7\x44\x24\x28\x00\x00\x00\x00\x50\x41\x52\x4c\x8b\x8c\x24\x08\x01\x00\x00\x4c\x8b\x84\x24\x00\x01\x00\x00\x48\x8b\x8c\x24\xf8\x00\x00\x00\x48\x8b\x94\x24\xf0\x00\x00\x00\x48\x8b\xb4\x24\xe8\x00\x00\x00\x48\x8b\xbc\x24\xe0\x00\x00\x00\xe8\x05\xec\xff\xff\x84\xc0\x5a\x59\x75\x78\x48\xc7\x84\x24\x00\x01\x00\x00\x00\x00\x00\x00\x4c\x09\x54\x24\x28\x48\x83\xec\x50\x48\x8d\xb4\x24\x20\x01\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x41\x57\x4c\x89\xee\x4c\x89\xe7\x41\x56\x53\x55\x48\x8b\x8c\x24\x80\x00\x00\x00\x4c\x8b\x8c\x24\x90\x00\x00\x00\x4c\x8b\x84\x24\x88\x00\x00\x00\x48\x8b\x54\x24\x78\xe8\xe1\xf8\xff\xff\x48\x8d\xbc\x24\x40\x01\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xe6\xf3\xa5\x4c\x8b\x94\x24\x70\x01\x00\x00\x48\x83\xc4\x70\xe9\x4a\xff\xff\xff\x48\x8b\x44\x24\x08\x4c\x09\xe8\x48\x0b\x44\x24\x10\x48\x0b\x44\x24\x18\x48\x0b\x44\x24\x20\x48\x09\xe8\x48\x31\xd8\x48\x23\x44\x24\x28\x48\x8b\x9c\x24\x18\x01\x00\x00\x64\x48\x33\x1c\x25\x28\x00\x00\x00\x48\x0f\xc8\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x28\x01\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\x49\x89\xf7\x41\x55\x41\x54\x49\x89\xf5\x55\x53\x49\xc1\xff\x20\x48\x81\xec\xa8\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x98\x00\x00\x00\x31\xc0\x48\x8b\x84\x24\xe8\x00\x00\x00\x4c\x8b\xb4\x24\xe0\x00\x00\x00\x4c\x8b\xa4\x24\xf0\x00\x00\x00\x48\x8b\x9c\x24\xf8\x00\x00\x00\x48\x8b\xac\x24\x00\x01\x00\x00\x48\x89\x7c\x24\x30\x48\x89\x44\x24\x10\x48\x8b\x84\x24\x08\x01\x00\x00\x4c\x89\xf7\x89\x74\x24\x18\x48\x89\xd9\x4c\x89\xe2\x49\x89\xe8\x48\x89\x44\x24\x08\x48\x8b\x84\x24\x20\x01\x00\x00\x48\x89\x44\x24\x28\x56\x48\x8b\x74\x24\x18\x4c\x8b\x4c\x24\x10\xe8\xd4\xea\xff\xff\x48\x8b\x74\x24\x18\x4c\x8b\x4c\x24\x10\x4c\x89\xf7\x89\x44\x24\x20\x44\x89\xf8\x49\x89\xe8\xc1\xf8\x06\x41\x83\xe7\x3f\x48\x89\xd9\x4c\x89\xe2\x89\x44\x24\x40\x44\x89\x3c\x24\xe8\xa3\xea\xff\xff\x5f\x85\xc0\x89\x44\x24\x1c\x75\x1f\x48\x8b\x84\x24\x10\x01\x00\x00\x44\x8b\x94\x24\x18\x01\x00\x00\x4c\x8b\x5c\x24\x28\x48\x89\x44\x24\x20\xe9\xc5\x00\x00\x00\x8b\x44\x24\x1c\x49\x89\xe8\x48\x89\xd9\x4c\x89\xe2\x4c\x89\xf7\x50\x4c\x8b\x4c\x24\x10\x48\x8b\x74\x24\x18\xe8\xe0\xea\xff\xff\x5e\x44\x88\xf9\x48\xc7\xc2\xfe\xff\xff\xff\x48\xd3\xc2\xb9\x12\x00\x00\x00\x48\x21\xc2\x4c\x8d\x44\x24\x40\x48\x83\xec\x48\x48\x89\xe7\x48\x8d\xb4\x24\x28\x01\x00\x00\xf3\xa5\x4c\x89\xc7\x8b\x74\x24\x64\xe8\x64\xe8\xff\xff\x48\x8d\xbc\x24\x28\x01\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xc6\xf3\xa5\x48\x8b\x84\x24\x30\x01\x00\x00\x4c\x8b\xb4\x24\x28\x01\x00\x00\x4c\x8b\xa4\x24\x38\x01\x00\x00\x48\x8b\x9c\x24\x40\x01\x00\x00\x48\x8b\xac\x24\x48\x01\x00\x00\x44\x8b\x94\x24\x60\x01\x00\x00\x48\x89\x44\x24\x58\x48\x8b\x84\x24\x50\x01\x00\x00\x4c\x8b\x9c\x24\x68\x01\x00\x00\x48\x89\x44\x24\x50\x48\x8b\x84\x24\x58\x01\x00\x00\x48\x89\x44\x24\x68\x48\x83\xc4\x48\x83\x7c\x24\x38\x00\x0f\x85\xd0\x00\x00\x00\x8b\x44\x24\x18\x44\x89\x54\x24\x38\x48\x89\xd9\x4c\x89\xf7\x49\x89\xe8\x4c\x89\xe2\x50\x4c\x8b\x4c\x24\x10\x48\x8b\x74\x24\x18\xe8\x0b\xea\xff\xff\x59\x49\x63\xcd\x31\xff\x44\x8b\x54\x24\x38\x48\x83\xf9\x3f\x77\x08\xbf\x01\x00\x00\x00\x48\xd3\xe7\x48\x89\x9c\x24\xf8\x00\x00\x00\x48\x8b\x5c\x24\x08\x48\xf7\xd7\x48\x8b\x54\x24\x10\x48\x21\xc7\x44\x88\xf9\xbe\x01\x00\x00\x00\x4c\x89\xb4\x24\xe0\x00\x00\x00\x4c\x89\xa4\x24\xf0\x00\x00\x00\x48\x89\x9c\x24\x08\x01\x00\x00\x48\x8b\x5c\x24\x20\x48\xd3\xe6\x48\x89\x94\x24\xe8\x00\x00\x00\x48\x89\xac\x24\x00\x01\x00\x00\x48\x89\xfa\x44\x89\x94\x24\x18\x01\x00\x00\x4c\x89\x9c\x24\x20\x01\x00\x00\x4c\x8d\x44\x24\x40\x48\x89\x9c\x24\x10\x01\x00\x00\x48\x83\xec\x48\x48\x09\xf2\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x28\x01\x00\x00\xf3\xa5\x8b\x74\x24\x60\xe9\xcb\x00\x00\x00\x8b\x44\x24\x38\x44\x89\x54\x24\x3c\x48\x89\xd9\x4c\x89\xe2\x49\x89\xe8\x4c\x89\xf7\x50\x48\x8b\x74\x24\x18\x4c\x8b\x4c\x24\x10\xe8\x3b\xe9\xff\xff\x49\x63\xcd\x31\xf6\x5a\x48\x83\xf9\x3f\x44\x8b\x54\x24\x3c\x77\x08\xbe\x01\x00\x00\x00\x48\xd3\xe6\x48\x89\x9c\x24\xf8\x00\x00\x00\x48\x8b\x5c\x24\x08\x48\xf7\xd6\x48\x8b\x54\x24\x10\x4c\x89\xb4\x24\xe0\x00\x00\x00\x44\x88\xf9\x4c\x89\xa4\x24\xf0\x00\x00\x00\x48\x89\xac\x24\x00\x01\x00\x00\x4c\x8d\x44\x24\x40\x48\x21\xf3\x44\x89\x94\x24\x18\x01\x00\x00\x4c\x89\x9c\x24\x20\x01\x00\x00\x48\x89\x9c\x24\x08\x01\x00\x00\x48\x8b\x5c\x24\x20\x48\x83\xec\x48\x48\x89\x94\x24\x30\x01\x00\x00\xba\x01\x00\x00\x00\x48\xd3\xe2\xb9\x12\x00\x00\x00\x48\x89\x9c\x24\x58\x01\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x28\x01\x00\x00\xf3\xa5\x48\x09\xc2\x8b\xb4\x24\x80\x00\x00\x00\x4c\x89\xc7\xe8\x49\xe6\xff\xff\x48\x8d\xbc\x24\x28\x01\x00\x00\x4c\x89\xc6\xb9\x12\x00\x00\x00\xf3\xa5\xba\xff\x00\x00\x00\x4c\x8b\x84\x24\x28\x01\x00\x00\x48\x8b\xac\x24\x30\x01\x00\x00\x48\x8b\x9c\x24\x38\x01\x00\x00\x4c\x8b\x9c\x24\x40\x01\x00\x00\x4c\x8b\x94\x24\x48\x01\x00\x00\x4c\x8b\x8c\x24\x50\x01\x00\x00\x48\x8b\xbc\x24\x58\x01\x00\x00\x8b\x84\x24\x60\x01\x00\x00\x48\x8b\xb4\x24\x68\x01\x00\x00\x48\x83\xc4\x48\x83\x7c\x24\x18\x06\x75\x24\x41\x39\xc7\x75\x42\x41\x8d\x4f\xf8\x31\xc0\x48\x63\xc9\x48\x83\xf9\x3f\x77\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\xf7\xd0\x49\x21\xc1\xeb\x23\x83\x7c\x24\x18\x05\x0f\x94\xc1\x41\x83\xff\x06\x0f\x94\xc0\x20\xc8\x74\x0c\xf6\x44\x24\x28\x01\x74\x2e\xe9\x57\x01\x00\x00\x88\xc8\xeb\x25\x44\x89\xe8\x41\xbc\x08\x00\x00\x00\x44\x89\xf9\x99\xc1\xf9\x03\x41\xf7\xfc\x41\x8d\x55\x08\x29\xc1\x83\xf9\x02\x74\xbf\x31\xc0\xba\xff\x00\x00\x00\x41\x83\xff\x02\x75\x0f\x84\xc0\x74\x0b\xf6\x44\x24\x28\x02\x0f\x85\x32\x01\x00\x00\x83\x7c\x24\x18\x01\x0f\x94\xc1\x41\x83\xfd\x07\x41\x0f\x94\xc4\x41\x84\xcc\x74\x0f\x49\x89\xf4\x49\x83\xe4\xfe\x40\xf6\xc6\x01\x49\x0f\x45\xf4\x45\x85\xed\x41\x0f\x94\xc4\x41\x84\xcc\x74\x0f\x48\x89\xf1\x48\x83\xe1\xfd\x40\xf6\xc6\x02\x48\x0f\x45\xf1\x83\x7c\x24\x1c\x01\x0f\x94\xc1\x41\x83\xff\x3f\x75\x0d\x49\x89\xf4\x49\x83\xe4\xfb\x84\xc9\x49\x0f\x45\xf4\x41\x83\xff\x38\x75\x0d\x49\x89\xf4\x49\x83\xe4\xf7\x84\xc9\x49\x0f\x45\xf4\x48\x89\xf1\x48\x83\xe1\xfc\x84\xc0\x48\x0f\x45\xf1\x49\x63\xcd\x31\xc0\x48\x83\xf9\x3f\x77\x08\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\xf7\xd0\x44\x88\xf9\x48\x89\x9c\x24\xf0\x00\x00\x00\x48\x21\xc7\xb8\x01\x00\x00\x00\x48\x89\xb4\x24\x20\x01\x00\x00\x48\xd3\xe0\x4c\x89\x84\x24\xe0\x00\x00\x00\x48\x89\xac\x24\xe8\x00\x00\x00\x48\x09\xc7\x4c\x89\x9c\x24\xf8\x00\x00\x00\x4c\x89\x94\x24\x00\x01\x00\x00\x48\x8b\x9c\x24\x98\x00\x00\x00\x64\x48\x33\x1c\x25\x28\x00\x00\x00\x48\x89\xbc\x24\x10\x01\x00\x00\x4c\x89\x8c\x24\x08\x01\x00\x00\xb9\x12\x00\x00\x00\x89\x94\x24\x18\x01\x00\x00\x48\x8b\x7c\x24\x30\x48\x8d\xb4\x24\xe0\x00\x00\x00\x48\x8b\x44\x24\x30\xf3\xa5\x74\x37\xe8\x00\x00\x00\x00\x41\x80\xe0\x7f\x40\x80\xe7\x7f\x48\x83\xe6\xfe\x49\x83\xc8\x20\x48\x83\xcf\x20\xe9\xb9\xfe\xff\xff\x49\x83\xe0\xfe\x48\x83\xe7\xfe\x48\x83\xe6\xfd\x49\x83\xc8\x08\x48\x83\xcf\x08\xe9\xb5\xfe\xff\xff\x48\x81\xc4\xa8\x00\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x53\x48\x89\xf8\xb9\x12\x00\x00\x00\x48\x81\xec\xa0\x00\x00\x00\x64\x48\x8b\x14\x25\x28\x00\x00\x00\x48\x89\x94\x24\x98\x00\x00\x00\x31\xd2\x48\x8d\x5c\x24\x08\x48\x83\xec\x50\x48\x89\xe7\x48\x8d\xb4\x24\x00\x01\x00\x00\xf3\xa5\x48\x89\xc6\x48\x89\xdf\xe8\x0f\xfa\xff\xff\x48\x8b\x54\x24\x78\x48\x8b\x84\x24\x88\x00\x00\x00\x48\x8d\xbc\x24\xa0\x00\x00\x00\x48\x89\xde\xb9\x12\x00\x00\x00\xf3\xa5\x48\x89\x94\x24\xc0\x00\x00\x00\x48\x89\x84\x24\xd0\x00\x00\x00\x48\x8d\xb4\x24\xa0\x00\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\x48\x89\xc3\x48\x21\xd3\xf3\xa5\xe8\x5e\xf7\xff\xff\x48\x83\xc4\x50\x48\x85\xc3\x0f\x95\xc0\x48\x8b\x94\x24\x98\x00\x00\x00\x64\x48\x33\x14\x25\x28\x00\x00\x00\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\xa0\x00\x00\x00\x5b\xc3\x41\x57\x41\x56\xb9\x12\x00\x00\x00\x41\x55\x41\x54\x55\x53\x48\x89\xfd\x48\x81\xec\x08\x01\x00\x00\x48\x8b\x84\x24\x50\x01\x00\x00\x4c\x8b\x8c\x24\x68\x01\x00\x00\x48\x89\xe7\x4c\x8b\xac\x24\x40\x01\x00\x00\x4c\x8b\xb4\x24\x48\x01\x00\x00\x48\x8d\xb4\x24\x40\x01\x00\x00\x4c\x8b\xbc\x24\x58\x01\x00\x00\x48\x8b\x9c\x24\x60\x01\x00\x00\x48\x89\x44\x24\x60\x4c\x89\x4c\x24\x68\x4c\x8b\xa4\x24\x80\x01\x00\x00\xf3\xa5\x48\x89\xef\xe8\xd5\xfe\xff\xff\x48\x83\xc4\x50\x31\xd2\x84\xc0\x0f\x85\x6a\x01\x00\x00\x48\x89\xe8\x4c\x89\xf9\x49\x89\xd8\x48\xc1\xf8\x20\x4c\x89\xf6\x4c\x89\xef\x48\x89\x44\x24\x08\x50\x55\x4c\x8b\x4c\x24\x28\x48\x8b\x54\x24\x20\xe8\x5f\xe4\xff\xff\x83\xf8\x05\x5a\x59\x0f\x85\x30\x01\x00\x00\x83\x7c\x24\x08\x06\x0f\x85\x8b\x00\x00\x00\x41\x80\xe4\x01\x0f\x84\x1b\x01\x00\x00\x48\x83\xec\x50\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x40\x01\x00\x00\xf3\xa5\x48\xbf\x04\x00\x00\x00\x05\x00\x00\x00\xe8\x59\xfe\xff\xff\x48\x83\xc4\x50\x31\xd2\x84\xc0\x0f\x85\xea\x00\x00\x00\x48\x8b\x84\x24\x20\x01\x00\x00\x48\x8d\x7c\x24\x20\x48\x8d\xb4\x24\xf0\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x83\xec\x50\xf3\xa5\x48\x89\x84\x24\xa0\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x8d\x74\x24\x70\x48\x89\xe7\x48\x21\xc3\xf3\xa5\xe8\xfa\xf5\xff\xff\x48\x83\xc4\x50\x48\x85\xc3\x0f\x94\xc2\xe9\x9c\x00\x00\x00\x83\x7c\x24\x08\x02\x0f\x85\x8f\x00\x00\x00\x41\x80\xe4\x02\x0f\x84\x85\x00\x00\x00\x48\x83\xec\x50\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x40\x01\x00\x00\xf3\xa5\x48\xbf\x04\x00\x00\x00\x03\x00\x00\x00\xe8\xc3\xfd\xff\xff\x48\x83\xc4\x50\x84\xc0\x75\x50\x48\x8b\x84\x24\x20\x01\x00\x00\x48\x8d\x7c\x24\x68\x48\x8d\xb4\x24\xf0\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x83\xec\x50\xf3\xa5\x48\x89\x84\x24\xe8\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\xb8\x00\x00\x00\x48\x89\xe7\x48\x21\xc3\xf3\xa5\xe8\x67\xf5\xff\xff\x48\x83\xc4\x50\x48\x85\xc3\xb2\x01\x0f\x94\xc0\xeb\x04\xb2\x01\x31\xc0\x21\xc2\xeb\x06\xb2\x01\xb0\x01\xeb\xf6\x48\x81\xc4\xb8\x00\x00\x00\x88\xd0\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x55\x53\x48\x81\xec\x88\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x44\x24\x78\x31\xc0\x48\x8b\x9c\x24\x08\x01\x00\x00\x48\x8d\x44\x24\x20\x48\x8b\xac\x24\x10\x01\x00\x00\x4c\x8b\xa4\x24\x18\x01\x00\x00\x4c\x8b\xac\x24\x20\x01\x00\x00\x4c\x8b\xb4\x24\x28\x01\x00\x00\x4c\x8b\xbc\x24\x30\x01\x00\x00\x4c\x8b\x9c\x24\x38\x01\x00\x00\x48\x89\x3c\x24\x48\x89\x44\x24\x08\x48\x89\x9c\x24\x08\x01\x00\x00\x48\x89\xac\x24\x10\x01\x00\x00\x48\x83\xec\x50\x4c\x89\xa4\x24\x68\x01\x00\x00\x4c\x89\xac\x24\x70\x01\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xb4\x24\x78\x01\x00\x00\x4c\x89\xbc\x24\x80\x01\x00\x00\x4c\x89\x9c\x24\x88\x01\x00\x00\x48\x8d\xb4\x24\x58\x01\x00\x00\x48\x89\xe7\xf3\xa5\xff\xb4\x24\x50\x01\x00\x00\x8b\x84\x24\x50\x01\x00\x00\x50\xff\xb4\x24\x50\x01\x00\x00\xff\xb4\x24\x50\x01\x00\x00\x4c\x8b\x8c\x24\x50\x01\x00\x00\x4c\x8b\x84\x24\x48\x01\x00\x00\x48\x8b\x8c\x24\x40\x01\x00\x00\x48\x8b\x94\x24\x38\x01\x00\x00\x48\x8b\xb4\x24\x30\x01\x00\x00\x48\x8b\x7c\x24\x78\xe8\x07\xef\xff\xff\x48\x8d\xbc\x24\x78\x01\x00\x00\x48\x8b\x74\x24\x78\xb9\x12\x00\x00\x00\xf3\xa5\x4c\x8b\x9c\x24\xa8\x01\x00\x00\x48\x8b\x9c\x24\x78\x01\x00\x00\x48\x8b\xac\x24\x80\x01\x00\x00\x4c\x8b\xa4\x24\x88\x01\x00\x00\x4c\x8b\xac\x24\x90\x01\x00\x00\x4c\x8b\xb4\x24\x98\x01\x00\x00\x4c\x8b\xbc\x24\xa0\x01\x00\x00\x48\x83\xc4\x68\x48\x89\xdf\x41\x53\x4c\x89\xe2\x48\x89\xee\x4c\x89\xe9\x4d\x89\xf0\x4d\x89\xf9\x4c\x89\x5c\x24\x28\xe8\x62\xe1\xff\xff\x5a\x59\x84\xc0\x48\x8d\x84\x24\x08\x01\x00\x00\x48\x89\x44\x24\x10\x75\x59\xff\xb4\x24\x48\x01\x00\x00\x4c\x8b\x5c\x24\x20\x4d\x89\xf9\x4d\x89\xf0\x4c\x89\xe9\x4c\x89\xe2\x48\x89\xee\x48\x89\xdf\x41\x53\x4c\x89\x5c\x24\x28\xe8\x96\xe3\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x10\x01\x00\x00\xf3\xa5\x48\x89\xc7\xe8\x37\xfc\xff\xff\x48\x83\xc4\x50\x84\xc0\x4c\x8b\x5c\x24\x18\x0f\x84\x89\xfe\xff\xff\x48\x8b\x54\x24\x78\x64\x48\x33\x14\x25\x28\x00\x00\x00\xb9\x12\x00\x00\x00\x48\x8b\x3c\x24\x48\x8b\x74\x24\x10\x48\x8b\x04\x24\xf3\xa5\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x88\x00\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x55\x53\xb9\x12\x00\x00\x00\x48\x89\xfb\x48\x81\xec\xb8\x00\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\xa8\x00\x00\x00\x31\xc0\x48\x89\xe7\x48\x8d\xb4\x24\xd0\x00\x00\x00\xf3\xa5\x48\x89\xdf\xe8\x28\xf1\xff\xff\x48\x8b\x4b\x18\x48\x8b\x53\x10\x48\x83\xc4\x50\x48\x8b\x73\x08\x4c\x8b\x4b\x28\x4c\x8b\x43\x20\x48\x8b\x3b\xff\x73\x40\xff\x73\x30\xe8\xcd\xe2\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\xd0\x00\x00\x00\xf3\xa5\x48\x89\xc7\xe8\x6e\xfb\xff\xff\x48\x83\xc4\x50\x84\xc0\x75\x46\x48\x89\xe5\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x89\xde\x48\x83\xec\x48\xf3\xa5\x48\x89\xe7\x48\x8d\xb4\x24\x10\x01\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x89\xef\xe8\x30\xfd\xff\xff\xb9\x12\x00\x00\x00\x48\x89\xdf\x48\x89\xee\xf3\xa5\x48\x81\xc4\x90\x00\x00\x00\x48\x8b\x54\x24\x58\x64\x48\x33\x14\x25\x28\x00\x00\x00\x48\x89\xd8\x74\x05\xe8\x00\x00\x00\x00\x48\x83\xc4\x68\x5b\x5d\xc3\x41\x57\x41\x56\x41\x55\x41\x54\x55\x53\x48\x81\xec\x68\x01\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x58\x01\x00\x00\x31\xc0\x85\xff\xb8\x01\x00\x00\x00\x0f\x84\x14\x02\x00\x00\x89\x7c\x24\x18\x48\x8d\x84\x24\x80\x00\x00\x00\x48\x83\xec\x50\x48\x89\xe7\x48\x8d\xb4\x24\xf0\x01\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x89\xc7\xe8\xbb\xfe\xff\xff\x48\x83\xc4\x50\x8b\x54\x24\x18\x48\x8b\xac\x24\xb0\x00\x00\x00\x48\x8d\x84\x24\x10\x01\x00\x00\x4c\x8b\xa4\x24\xa8\x00\x00\x00\x4c\x8b\xac\x24\xa0\x00\x00\x00\x4c\x8b\xb4\x24\x98\x00\x00\x00\x4c\x8b\xbc\x24\x90\x00\x00\x00\x48\x89\x44\x24\x08\x48\x8d\x84\x24\xc8\x00\x00\x00\x48\x8b\x9c\x24\x88\x00\x00\x00\x4c\x8b\x9c\x24\x80\x00\x00\x00\x48\xc7\x04\x24\x00\x00\x00\x00\x48\x89\x44\x24\x10\x8d\x42\xff\x89\x44\x24\x24\x48\x8d\x44\x24\x30\x48\x89\x44\x24\x18\x52\x55\x4c\x89\xf1\x48\x89\xde\x4d\x89\xe1\x4d\x89\xe8\x4c\x89\xfa\x4c\x89\xdf\x4c\x89\x5c\x24\x38\xe8\xe5\xde\xff\xff\x84\xc0\x59\x5e\x0f\x85\x4b\x01\x00\x00\xff\xb4\x24\xc0\x00\x00\x00\x55\x4d\x89\xe1\x4c\x8b\x5c\x24\x38\x4d\x89\xe8\x4c\x89\xfa\x4c\x89\xf1\x48\x89\xde\x4c\x89\xdf\xe8\x28\xe1\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\xf0\x01\x00\x00\xf3\xa5\x48\x89\xc6\x48\x8b\x7c\x24\x58\xe8\x5c\xf3\xff\xff\x48\x8b\x74\x24\x58\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\x7c\x24\x60\xe8\x4c\xdd\xff\xff\x48\x8b\x74\x24\x60\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x8b\x7c\x24\x74\xe8\x92\xfe\xff\xff\x4c\x8b\x5c\x24\x78\x48\x89\x9c\x24\xd8\x00\x00\x00\xb9\x12\x00\x00\x00\x4c\x89\xbc\x24\xe0\x00\x00\x00\x4c\x89\xb4\x24\xe8\x00\x00\x00\x4c\x89\xac\x24\xf0\x00\x00\x00\x4c\x89\xa4\x24\xf8\x00\x00\x00\x4c\x89\x9c\x24\xd0\x00\x00\x00\x48\x89\xac\x24\x00\x01\x00\x00\x48\x01\x44\x24\x50\x58\x48\x8d\xb4\x24\xc8\x00\x00\x00\x48\x89\xe7\x48\x83\xec\x48\xf3\xa5\x48\x89\xe7\x48\x8d\xb4\x24\x30\x02\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\xa8\x00\x00\x00\xe8\x17\xfb\xff\xff\x48\x8d\xbc\x24\x10\x01\x00\x00\x48\x8b\xb4\x24\xa8\x00\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x4c\x8b\x9c\x24\x10\x01\x00\x00\x48\x8b\x9c\x24\x18\x01\x00\x00\x4c\x8b\xbc\x24\x20\x01\x00\x00\x4c\x8b\xb4\x24\x28\x01\x00\x00\x4c\x8b\xac\x24\x30\x01\x00\x00\x4c\x8b\xa4\x24\x38\x01\x00\x00\x48\x8b\xac\x24\x40\x01\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xe9\x8d\xfe\xff\xff\x48\x8b\x04\x24\x48\x8b\x9c\x24\x58\x01\x00\x00\x64\x48\x33\x1c\x25\x28\x00\x00\x00\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x68\x01\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x48\xb9\x55\x55\x55\x55\x55\x55\x55\x55\x48\x89\xfa\x48\xd1\xef\x48\x21\xca\x48\x21\xf9\x48\xb8\x33\x33\x33\x33\x33\x33\x33\x33\x48\x01\xca\x48\x89\xd1\x48\xc1\xea\x02\x48\x21\xc1\x48\x21\xd0\x48\x8d\x14\x01\x48\xb9\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x48\x89\xd0\x48\xc1\xea\x04\x48\x21\xc8\x48\x21\xca\x48\x01\xc2\x48\xb8\x01\x01\x01\x01\x01\x01\x01\x01\x48\x0f\xaf\xd0\x48\x89\xd0\x48\xc1\xe8\x38\xc3\x41\x57\x41\x56\xb9\x12\x00\x00\x00\x41\x55\x41\x54\x55\x53\x48\x81\xec\x48\x06\x00\x00\x64\x48\x8b\x04\x25\x28\x00\x00\x00\x48\x89\x84\x24\x38\x06\x00\x00\x31\xc0\x48\x8d\x84\x24\xb8\x01\x00\x00\x48\x83\xec\x50\x48\x89\xe7\x48\x8d\xb4\x24\xd0\x06\x00\x00\xf3\xa5\x48\x89\xc7\xe8\xf9\xfb\xff\xff\x48\x83\xc4\x50\x48\x8b\x84\x24\xe0\x01\x00\x00\x4c\x8b\xa4\x24\xe8\x01\x00\x00\xc7\x84\x24\x00\x01\x00\x00\xff\x00\x00\x00\xc7\x84\x24\x14\x01\x00\x00\xff\x00\x00\x00\xc7\x84\x24\x10\x01\x00\x00\x00\x00\x00\x8f\x48\x89\x44\x24\x30\x48\x8b\x84\x24\xd8\x01\x00\x00\x48\x89\x44\x24\x28\x48\x8b\x84\x24\xd0\x01\x00\x00\x48\x89\x44\x24\x18\x48\x8b\x84\x24\xc8\x01\x00\x00\x48\x89\x44\x24\x08\x48\x8b\x84\x24\xc0\x01\x00\x00\x48\x89\x44\x24\x20\x48\x8b\x84\x24\xb8\x01\x00\x00\x48\x89\x44\x24\x10\x48\x8d\x84\x24\x00\x02\x00\x00\x48\x89\x84\x24\x40\x01\x00\x00\x48\x8d\x84\x24\x90\x02\x00\x00\x48\x89\x84\x24\x48\x01\x00\x00\x48\x8d\x84\x24\xd8\x02\x00\x00\x48\x89\x84\x24\x28\x01\x00\x00\x48\x8d\x84\x24\x68\x03\x00\x00\x48\x89\x84\x24\x50\x01\x00\x00\x41\x57\x41\x54\x4c\x8b\x4c\x24\x40\x4c\x8b\x44\x24\x38\x48\x8b\x4c\x24\x28\x48\x8b\x54\x24\x18\x48\x8b\x74\x24\x30\x48\x8b\x7c\x24\x20\xe8\xd2\xdb\xff\xff\x84\xc0\x5a\x59\x0f\x85\x42\x0c\x00\x00\xff\xb4\x24\xf8\x01\x00\x00\x41\x54\x48\x8b\x4c\x24\x28\x4c\x8b\x4c\x24\x40\x4c\x8b\x44\x24\x38\x48\x8b\x54\x24\x18\x48\x8b\x74\x24\x30\x48\x8b\x7c\x24\x20\xe8\x0d\xde\xff\xff\x48\x83\xec\x40\x48\x89\x84\x24\x48\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\xd0\x06\x00\x00\xf3\xa5\x48\x8b\xb4\x24\x48\x01\x00\x00\x48\x8b\xbc\x24\x90\x01\x00\x00\xe8\x31\xf0\xff\xff\x48\x8d\xbc\x24\x98\x02\x00\x00\x48\x8d\xb4\x24\xd0\x06\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8d\xb4\x24\x98\x02\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\x98\x01\x00\x00\xe8\x78\xfa\xff\xff\x48\x8b\x84\x24\xe0\x02\x00\x00\x4c\x8b\xac\x24\x10\x03\x00\x00\x48\x89\x84\x24\x88\x00\x00\x00\x48\x8b\x84\x24\xe8\x02\x00\x00\x48\x89\x84\x24\x90\x00\x00\x00\x48\x8b\x84\x24\xf0\x02\x00\x00\x48\x89\x84\x24\x98\x00\x00\x00\x48\x8b\x84\x24\xf8\x02\x00\x00\x48\x89\x84\x24\xa0\x00\x00\x00\x48\x8b\x84\x24\x00\x03\x00\x00\x48\x89\x84\x24\xa8\x00\x00\x00\x48\x8b\x84\x24\x08\x03\x00\x00\x48\x89\x84\x24\xb0\x00\x00\x00\x48\x83\xc4\x50\x48\x8d\x84\x24\xb0\x03\x00\x00\xc7\x44\x24\x04\x00\x00\x00\x8f\x48\x89\x84\x24\x20\x01\x00\x00\x48\x8d\x84\x24\x40\x04\x00\x00\x48\x89\x84\x24\x38\x01\x00\x00\x53\x41\x55\x4c\x8b\x4c\x24\x70\x4c\x8b\x44\x24\x68\x48\x8b\x4c\x24\x60\x48\x8b\x54\x24\x58\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x48\xe8\x79\xda\xff\xff\x84\xc0\x5d\x41\x5e\x0f\x85\x9a\x09\x00\x00\xff\xb4\x24\xd0\x02\x00\x00\x41\x55\x48\x8b\x4c\x24\x60\x4c\x8b\x4c\x24\x70\x4c\x8b\x44\x24\x68\x48\x8b\x54\x24\x58\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x48\xe8\xb3\xdc\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\x98\x02\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xc6\x48\x8b\xbc\x24\x78\x01\x00\x00\xe8\xe4\xee\xff\xff\x48\x8b\xb4\x24\x78\x01\x00\x00\x48\x8d\xbc\x24\x70\x03\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8d\xb4\x24\x70\x03\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\xa0\x01\x00\x00\xe8\x2b\xf9\xff\xff\x48\x8b\x84\x24\xb8\x03\x00\x00\x4c\x8b\xb4\x24\xe8\x03\x00\x00\x48\x89\x84\x24\xb8\x00\x00\x00\x48\x8b\x84\x24\xc0\x03\x00\x00\x48\x89\x84\x24\xc0\x00\x00\x00\x48\x8b\x84\x24\xc8\x03\x00\x00\x48\x89\x84\x24\xc8\x00\x00\x00\x48\x8b\x84\x24\xd0\x03\x00\x00\x48\x89\x84\x24\xd0\x00\x00\x00\x48\x8b\x84\x24\xd8\x03\x00\x00\x48\x89\x84\x24\xd8\x00\x00\x00\x48\x8b\x84\x24\xe0\x03\x00\x00\x48\x89\x84\x24\xe0\x00\x00\x00\x48\x83\xc4\x50\x48\x8d\x84\x24\x88\x04\x00\x00\xc7\x84\x24\xc8\x00\x00\x00\x00\x00\x00\x8f\x48\x89\x84\x24\x18\x01\x00\x00\x48\x8d\x84\x24\xf0\x05\x00\x00\x48\x89\x84\x24\x30\x01\x00\x00\x41\x51\x41\x56\x4c\x8b\x8c\x24\xa0\x00\x00\x00\x4c\x8b\x84\x24\x98\x00\x00\x00\x48\x8b\x8c\x24\x90\x00\x00\x00\x48\x8b\x94\x24\x88\x00\x00\x00\x48\x8b\xb4\x24\x80\x00\x00\x00\x48\x8b\x7c\x24\x78\xe8\x19\xd9\xff\xff\x84\xc0\x41\x5a\x41\x5b\x0f\x85\xf9\x06\x00\x00\xff\xb4\x24\xa8\x03\x00\x00\x41\x56\x48\x8b\x8c\x24\x90\x00\x00\x00\x4c\x8b\x8c\x24\xa0\x00\x00\x00\x4c\x8b\x84\x24\x98\x00\x00\x00\x48\x8b\x94\x24\x88\x00\x00\x00\x48\x8b\xb4\x24\x80\x00\x00\x00\x48\x8b\x7c\x24\x78\xe8\x43\xdb\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\x70\x03\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xc6\x48\x8b\xbc\x24\x70\x01\x00\x00\xe8\x74\xed\xff\xff\x48\x8b\xb4\x24\x70\x01\x00\x00\x48\x8d\xbc\x24\x48\x04\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8d\xb4\x24\x48\x04\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\x88\x01\x00\x00\xe8\xbb\xf7\xff\xff\x48\x8b\x84\x24\x90\x04\x00\x00\x4c\x8b\xbc\x24\xc0\x04\x00\x00\x48\x89\x84\x24\xe8\x00\x00\x00\x48\x8b\x84\x24\x98\x04\x00\x00\x48\x89\x84\x24\xf0\x00\x00\x00\x48\x8b\x84\x24\xa0\x04\x00\x00\x48\x89\x84\x24\xf8\x00\x00\x00\x48\x8b\x84\x24\xa8\x04\x00\x00\x48\x89\x84\x24\x00\x01\x00\x00\x48\x8b\x84\x24\xb0\x04\x00\x00\x48\x89\x84\x24\x08\x01\x00\x00\x48\x8b\x84\x24\xb8\x04\x00\x00\x48\x89\x84\x24\x10\x01\x00\x00\x48\x83\xc4\x50\x48\x8d\x84\x24\x60\x01\x00\x00\xc7\x84\x24\xcc\x00\x00\x00\x00\x00\x00\x8f\x48\x89\x84\x24\xd0\x00\x00\x00\x56\x41\x57\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x4c\x8b\x84\x24\xc8\x00\x00\x00\x48\x8b\x8c\x24\xc0\x00\x00\x00\x48\x8b\x94\x24\xb8\x00\x00\x00\x48\x8b\xb4\x24\xb0\x00\x00\x00\x48\x8b\xbc\x24\xa8\x00\x00\x00\xe8\xb7\xd7\xff\xff\x84\xc0\x5f\x41\x58\x0f\x85\x4f\x04\x00\x00\xff\xb4\x24\x80\x04\x00\x00\x41\x57\x4c\x8b\x8c\x24\xd0\x00\x00\x00\x4c\x8b\x84\x24\xc8\x00\x00\x00\x48\x8b\x8c\x24\xc0\x00\x00\x00\x48\x8b\x94\x24\xb8\x00\x00\x00\x48\x8b\xb4\x24\xb0\x00\x00\x00\x48\x8b\xbc\x24\xa8\x00\x00\x00\xe8\xdf\xd9\xff\xff\x48\x83\xec\x40\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\x48\x04\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xc6\x48\x8b\xbc\x24\x68\x01\x00\x00\xe8\x10\xec\xff\xff\x48\x8b\xb4\x24\x68\x01\x00\x00\x48\x8d\xbc\x24\x20\x05\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8d\xbc\x24\x68\x05\x00\x00\x48\x8d\xb4\x24\x20\x05\x00\x00\xb9\x12\x00\x00\x00\x48\x8b\x84\x24\x20\x05\x00\x00\x48\x8b\x94\x24\x48\x05\x00\x00\x48\x8b\x9c\x24\x50\x05\x00\x00\x48\x89\x84\x24\x28\x01\x00\x00\x48\x8b\x84\x24\x28\x05\x00\x00\xf3\xa5\x48\x89\xd7\x48\x89\x84\x24\x30\x01\x00\x00\x48\x8b\x84\x24\x30\x05\x00\x00\x48\x21\xdf\x48\x89\x84\x24\x38\x01\x00\x00\x48\x8b\x84\x24\x38\x05\x00\x00\x48\x89\x84\x24\x40\x01\x00\x00\x48\x83\xc4\x50\x48\x89\x94\x24\x58\x01\x00\x00\xe8\x00\x00\x00\x00\x48\x8b\xbc\x24\xe0\x00\x00\x00\x89\xc5\x6b\xed\x64\x48\x21\xdf\xe8\x00\x00\x00\x00\x48\x8b\xbc\x24\xe8\x00\x00\x00\x69\xc0\x2c\x01\x00\x00\x48\x21\xdf\x01\xc5\xe8\x00\x00\x00\x00\x48\x8b\xbc\x24\xd8\x00\x00\x00\x69\xc0\x2c\x01\x00\x00\x48\x21\xdf\x01\xc5\xe8\x00\x00\x00\x00\x48\x8b\xbc\x24\xf0\x00\x00\x00\x69\xc0\xf4\x01\x00\x00\x48\x21\xdf\x01\xc5\xe8\x00\x00\x00\x00\x69\xc0\x84\x03\x00\x00\x48\x8b\x94\x24\x58\x01\x00\x00\x48\x89\x9c\x24\x48\x05\x00\x00\x48\x8d\xbc\x24\x60\x05\x00\x00\x48\x8d\xb4\x24\x18\x05\x00\x00\xb9\x12\x00\x00\x00\x01\xc5\x48\x8b\x84\x24\xd8\x00\x00\x00\x48\x89\x94\x24\x40\x05\x00\x00\x48\x89\x84\x24\x18\x05\x00\x00\x48\x8b\x84\x24\xe0\x00\x00\x00\x48\x89\x84\x24\x20\x05\x00\x00\x48\x8b\x84\x24\xe8\x00\x00\x00\x48\x89\x84\x24\x28\x05\x00\x00\x48\x8b\x84\x24\xf0\x00\x00\x00\x48\x89\x84\x24\x30\x05\x00\x00\x48\x8b\x84\x24\xd8\x00\x00\x00\xf3\xa5\x48\x89\x9c\x24\x90\x05\x00\x00\x48\x89\x94\x24\x88\x05\x00\x00\x48\x8d\xbc\x24\xa8\x05\x00\x00\x48\x89\x84\x24\x60\x05\x00\x00\x48\x8b\x84\x24\xe0\x00\x00\x00\x48\x8d\xb4\x24\x60\x05\x00\x00\xb9\x12\x00\x00\x00\x31\xdb\x48\x89\x84\x24\x68\x05\x00\x00\x48\x8b\x84\x24\xe8\x00\x00\x00\x48\x89\x84\x24\x70\x05\x00\x00\x48\x8b\x84\x24\xf0\x00\x00\x00\x48\x89\x84\x24\x78\x05\x00\x00\x48\x83\xec\x50\xf3\xa5\x48\x8d\xb4\x24\xf8\x05\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\x80\x01\x00\x00\xe8\x98\xf4\xff\xff\x48\x83\xc4\x50\x50\xff\xb4\x24\x28\x06\x00\x00\x4c\x8b\x8c\x24\x28\x06\x00\x00\x4c\x8b\x84\x24\x20\x06\x00\x00\x48\x8b\x8c\x24\x18\x06\x00\x00\x48\x8b\x94\x24\x10\x06\x00\x00\x48\x8b\xb4\x24\x08\x06\x00\x00\x48\x8b\xbc\x24\x00\x06\x00\x00\xe8\x12\xd5\xff\xff\x84\xc0\x5a\x59\x75\x5e\x48\x83\xec\x48\xb9\x12\x00\x00\x00\xff\xc3\x48\x8d\xb4\x24\x38\x06\x00\x00\x48\x89\xe7\x48\x83\xec\x48\xf3\xa5\x48\x8d\xb4\x24\x38\x06\x00\x00\x48\x89\xe7\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\xbc\x24\x60\x01\x00\x00\xe8\xfd\xf1\xff\xff\x48\x8d\xbc\x24\x80\x06\x00\x00\x48\x8b\xb4\x24\x60\x01\x00\x00\xb9\x12\x00\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xf3\xa5\xe9\x5f\xff\xff\xff\x8d\x04\x9b\x85\xdb\xba\xc0\xbd\xf0\xff\x4c\x89\xbc\x24\x70\x04\x00\x00\xb9\x12\x00\x00\x00\x0f\x44\xc2\x01\xc5\x48\x8b\x84\x24\x98\x00\x00\x00\x39\xac\x24\xcc\x00\x00\x00\x0f\x4d\xac\x24\xcc\x00\x00\x00\x48\x83\xec\x48\x48\x89\x84\x24\x88\x04\x00\x00\x48\x8b\x84\x24\xe8\x00\x00\x00\x89\xac\x24\x14\x01\x00\x00\x48\x89\x84\x24\x90\x04\x00\x00\x48\x8b\x84\x24\xf0\x00\x00\x00\x48\x89\x84\x24\x98\x04\x00\x00\x48\x8b\x84\x24\xf8\x00\x00\x00\x48\x89\x84\x24\xa0\x04\x00\x00\x48\x8b\x84\x24\x00\x01\x00\x00\x48\x89\x84\x24\xa8\x04\x00\x00\x48\x8b\x84\x24\x08\x01\x00\x00\x48\x89\x84\x24\xb0\x04\x00\x00\x48\x8d\xb4\x24\x88\x04\x00\x00\x48\x89\xe7\xf3\xa5\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\x88\x04\x00\x00\x48\x89\xe7\xf3\xa5\x48\x8b\xbc\x24\x60\x01\x00\x00\xe8\x14\xf1\xff\xff\x48\x8d\xbc\x24\xd0\x04\x00\x00\x48\x8b\xb4\x24\x60\x01\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x48\x8b\x84\x24\xd0\x04\x00\x00\x4c\x8b\xbc\x24\x00\x05\x00\x00\x48\x89\x84\x24\x28\x01\x00\x00\x48\x8b\x84\x24\xd8\x04\x00\x00\x48\x89\x84\x24\x30\x01\x00\x00\x48\x8b\x84\x24\xe0\x04\x00\x00\x48\x89\x84\x24\x38\x01\x00\x00\x48\x8b\x84\x24\xe8\x04\x00\x00\x48\x89\x84\x24\x40\x01\x00\x00\x48\x8b\x84\x24\xf0\x04\x00\x00\x48\x89\x84\x24\x48\x01\x00\x00\x48\x8b\x84\x24\xf8\x04\x00\x00\x48\x89\x84\x24\x50\x01\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xe9\x6e\xfb\xff\xff\x8b\x84\x24\xcc\x00\x00\x00\x4c\x89\xb4\x24\x98\x03\x00\x00\x48\x8d\x9c\x24\x60\x01\x00\x00\xb9\x12\x00\x00\x00\xf7\xd8\x39\x84\x24\xc8\x00\x00\x00\x0f\x4d\x84\x24\xc8\x00\x00\x00\x48\x83\xec\x48\x89\x84\x24\x10\x01\x00\x00\x48\x8b\x84\x24\xb0\x00\x00\x00\x48\x89\x84\x24\xb0\x03\x00\x00\x48\x8b\x84\x24\xb8\x00\x00\x00\x48\x89\x84\x24\xb8\x03\x00\x00\x48\x8b\x84\x24\xc0\x00\x00\x00\x48\x89\x84\x24\xc0\x03\x00\x00\x48\x8b\x84\x24\xc8\x00\x00\x00\x48\x89\x84\x24\xc8\x03\x00\x00\x48\x8b\x84\x24\xd0\x00\x00\x00\x48\x89\x84\x24\xd0\x03\x00\x00\x48\x8b\x84\x24\xd8\x00\x00\x00\x48\x89\x84\x24\xd8\x03\x00\x00\x48\x8d\xb4\x24\xb0\x03\x00\x00\x48\x89\xe7\xf3\xa5\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\xb0\x03\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xdf\xe8\xc6\xef\xff\xff\x48\x8d\xbc\x24\xf8\x03\x00\x00\xb9\x12\x00\x00\x00\x48\x89\xde\xf3\xa5\x48\x8b\x84\x24\xf8\x03\x00\x00\x4c\x8b\xb4\x24\x28\x04\x00\x00\x48\x89\x84\x24\xf8\x00\x00\x00\x48\x8b\x84\x24\x00\x04\x00\x00\x48\x89\x84\x24\x00\x01\x00\x00\x48\x8b\x84\x24\x08\x04\x00\x00\x48\x89\x84\x24\x08\x01\x00\x00\x48\x8b\x84\x24\x10\x04\x00\x00\x48\x89\x84\x24\x10\x01\x00\x00\x48\x8b\x84\x24\x18\x04\x00\x00\x48\x89\x84\x24\x18\x01\x00\x00\x48\x8b\x84\x24\x20\x04\x00\x00\x48\x89\x84\x24\x20\x01\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xe9\xc5\xf8\xff\xff\x8b\x84\x24\xc8\x00\x00\x00\x4c\x89\xac\x24\xc0\x02\x00\x00\x48\x8d\x9c\x24\x60\x01\x00\x00\xb9\x12\x00\x00\x00\xf7\xd8\x39\x44\x24\x04\x0f\x4d\x44\x24\x04\x48\x83\xec\x48\x89\x44\x24\x4c\x48\x8b\x84\x24\x80\x00\x00\x00\x48\x89\x84\x24\xd8\x02\x00\x00\x48\x8b\x84\x24\x88\x00\x00\x00\x48\x89\x84\x24\xe0\x02\x00\x00\x48\x8b\x84\x24\x90\x00\x00\x00\x48\x89\x84\x24\xe8\x02\x00\x00\x48\x8b\x84\x24\x98\x00\x00\x00\x48\x89\x84\x24\xf0\x02\x00\x00\x48\x8b\x84\x24\xa0\x00\x00\x00\x48\x89\x84\x24\xf8\x02\x00\x00\x48\x8b\x84\x24\xa8\x00\x00\x00\x48\x89\x84\x24\x00\x03\x00\x00\x48\x8d\xb4\x24\xd8\x02\x00\x00\x48\x89\xe7\xf3\xa5\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x8d\xb4\x24\xd8\x02\x00\x00\x48\x89\xe7\xf3\xa5\x48\x89\xdf\xe8\x86\xee\xff\xff\x48\x8d\xbc\x24\x20\x03\x00\x00\xb9\x12\x00\x00\x00\x48\x89\xde\xf3\xa5\x48\x8b\x84\x24\x20\x03\x00\x00\x4c\x8b\xac\x24\x50\x03\x00\x00\x48\x89\x84\x24\xc8\x00\x00\x00\x48\x8b\x84\x24\x28\x03\x00\x00\x48\x89\x84\x24\xd0\x00\x00\x00\x48\x8b\x84\x24\x30\x03\x00\x00\x48\x89\x84\x24\xd8\x00\x00\x00\x48\x8b\x84\x24\x38\x03\x00\x00\x48\x89\x84\x24\xe0\x00\x00\x00\x48\x8b\x84\x24\x40\x03\x00\x00\x48\x89\x84\x24\xe8\x00\x00\x00\x48\x8b\x84\x24\x48\x03\x00\x00\x48\x89\x84\x24\xf0\x00\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xe9\x35\xf6\xff\xff\x8b\x5c\x24\x04\x39\x9c\x24\x10\x01\x00\x00\x7d\x29\x8b\x84\x24\xf8\x00\x00\x00\x89\x9c\x24\x10\x01\x00\x00\x89\x84\x24\x14\x01\x00\x00\x48\x8b\x84\x24\xf8\x00\x00\x00\x48\xc1\xe8\x20\x48\x89\x84\x24\x00\x01\x00\x00\x48\x8b\x44\x24\x10\x4c\x89\xa4\x24\xe8\x01\x00\x00\x48\x8d\x9c\x24\x60\x01\x00\x00\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x89\x84\x24\x00\x02\x00\x00\x48\x8b\x44\x24\x68\x48\x89\x84\x24\x08\x02\x00\x00\x48\x8b\x44\x24\x50\x48\x89\x84\x24\x10\x02\x00\x00\x48\x8b\x44\x24\x60\x48\x89\x84\x24\x18\x02\x00\x00\x48\x8b\x44\x24\x70\x48\x89\x84\x24\x20\x02\x00\x00\x48\x8b\x44\x24\x78\x48\x89\x84\x24\x28\x02\x00\x00\x48\x8d\xb4\x24\x00\x02\x00\x00\x48\x89\xe7\xf3\xa5\x48\x83\xec\x48\xb9\x12\x00\x00\x00\x48\x89\xe7\x48\x8d\xb4\x24\x10\x07\x00\x00\xf3\xa5\x48\x89\xdf\xe8\x38\xed\xff\xff\x48\x8d\xbc\x24\x48\x02\x00\x00\xb9\x12\x00\x00\x00\x48\x89\xde\xf3\xa5\x48\x8b\x84\x24\x48\x02\x00\x00\x4c\x8b\xa4\x24\x78\x02\x00\x00\x48\x89\x84\x24\xa0\x00\x00\x00\x48\x8b\x84\x24\x50\x02\x00\x00\x48\x89\x84\x24\xb0\x00\x00\x00\x48\x8b\x84\x24\x58\x02\x00\x00\x48\x89\x84\x24\x98\x00\x00\x00\x48\x8b\x84\x24\x60\x02\x00\x00\x48\x89\x84\x24\xa8\x00\x00\x00\x48\x8b\x84\x24\x68\x02\x00\x00\x48\x89\x84\x24\xb8\x00\x00\x00\x48\x8b\x84\x24\x70\x02\x00\x00\x48\x89\x84\x24\xc0\x00\x00\x00\x48\x81\xc4\x90\x00\x00\x00\xe9\x8d\xf3\xff\xff\x48\x8b\x84\x24\x00\x01\x00\x00\x8b\x94\x24\x14\x01\x00\x00\x48\xc1\xe0\x20\x48\x09\xd0\x48\x8b\x9c\x24\x38\x06\x00\x00\x64\x48\x33\x1c\x25\x28\x00\x00\x00\x74\x05\xe8\x00\x00\x00\x00\x48\x81\xc4\x48\x06\x00\x00\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x48\x81\xec\xa8\x00\x00\x00\x48\xba\x81\x00\x00\x00\x00\x00\x00\x81\x48\xb9\x24\x00\x00\x00\x00\x00\x00\x24\x48\x89\x54\x24\x58\x48\xba\x42\x00\x00\x00\x00\x00\x00\x42\x48\x89\x4c\x24\x68\x48\x89\x54\x24\x60\x48\xbe\x08\x00\x00\x00\x00\x00\x00\x08\x48\xba\x10\x00\x00\x00\x00\x00\x00\x10\x48\xb9\x00\xff\x00\x00\x00\x00\xff\x00\x48\x89\x74\x24\x70\x89\xf8\x48\x89\x8c\x24\x80\x00\x00\x00\x48\x89\x54\x24\x78\x48\x8d\x74\x24\x58\x48\xc7\x84\x24\x88\x00\x00\x00\xff\xff\x00\x00\xc7\x84\x24\x90\x00\x00\x00\xff\x00\x00\x00\x48\x89\xe7\x48\xc7\x84\x24\x98\x00\x00\x00\x0f\x00\x00\x00\xb9\x12\x00\x00\x00\xf3\xa5\x89\xc7\xe8\xd6\xee\xff\xff\x48\x81\xc4\xa8\x00\x00\x00\xc3' 6 | offset = 12867 7 | libc = CDLL('libc.so.6') 8 | 9 | src_ptr = c_char_p(shellcode) 10 | size = len(shellcode) 11 | 12 | code_ptr = libc.valloc(size) 13 | code_ptr = c_void_p(code_ptr) 14 | 15 | memmove(code_ptr, src_ptr, size) 16 | err = libc.mprotect(code_ptr, size, 0x7) 17 | if 0 != err: 18 | raise Exception("mprotect: " + str(code)) 19 | 20 | main_ptr = c_void_p(c_uint64(code_ptr.value).value + c_uint64(offset).value) 21 | fptr = cast(main_ptr, CFUNCTYPE(c_long, c_long)) 22 | result = fptr(depth) 23 | libc.free(code_ptr) 24 | return result 25 | return execute() 26 | $$ language plpythonu; 27 | -------------------------------------------------------------------------------- /sql/create-simple.sql: -------------------------------------------------------------------------------- 1 | create or replace function pf_simple () returns int stable as $$ 2 | from ctypes import (CDLL, c_long, c_char_p, c_void_p, memmove, cast, CFUNCTYPE) 3 | def execute(): 4 | shellcode = b'\xb8\x2a\x00\x00\x00\xc3' 5 | 6 | libc = CDLL('libc.so.6') 7 | 8 | src_ptr = c_char_p(shellcode) 9 | size = len(shellcode) 10 | 11 | code_ptr = libc.valloc(size) 12 | code_ptr = c_void_p(code_ptr) 13 | 14 | memmove(code_ptr, src_ptr, size) 15 | err = libc.mprotect(code_ptr, size, 0x7) 16 | if 0 != err: 17 | raise Exception("mprotect: " + str(err)) 18 | 19 | fptr = cast(code_ptr, CFUNCTYPE(c_long)) 20 | result = fptr() 21 | libc.free(code_ptr) 22 | return result 23 | return execute() 24 | $$ language plpythonu; 25 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #define DEBUG 1 2 | #define PRINT 1 3 | #include "chess.c" 4 | #include 5 | 6 | typedef void (*ft_action)(gamestate, move, int); 7 | 8 | void print_iterator(iterator i) 9 | { 10 | printf("ITERATOR\n"); 11 | printf("== Promotion piece: %lu\n", i.promotion_piece); 12 | printf("== Current pieces\n"); 13 | print_bitboard(i.current_piece_bb); 14 | printf("== Rooks\n"); 15 | print_bitboard(i.rooks_bb); 16 | printf("== Knights\n"); 17 | print_bitboard(i.knights_bb); 18 | printf("== Bishops\n"); 19 | print_bitboard(i.bishops_bb); 20 | printf("== Queens\n"); 21 | print_bitboard(i.queens_bb); 22 | printf("== Kings\n"); 23 | print_bitboard(i.kings_bb); 24 | printf("== Pawns\n"); 25 | print_bitboard(i.pawns_bb); 26 | } 27 | 28 | void print_move_stdout(move m) 29 | { 30 | char b[7]; 31 | print_move(m, b); 32 | printf("%s", b); 33 | } 34 | 35 | void print_gamestate(gamestate g) 36 | { 37 | for (int r = 8; r --> 0;) { 38 | for (int f = 0; f < 8; f++) { 39 | int pos = mkPosition(f, r); 40 | int piece = get_piece(g, pos); 41 | bool is_white = is_bit_set(g.current_player_bb, pos); 42 | char c = piece_char(piece, is_white); 43 | putchar(c); 44 | } 45 | putchar('\n'); 46 | } 47 | printf("Flags: "); 48 | if (! g.castle_flags) { putchar('-'); } 49 | else { 50 | if (g.castle_flags & CASTLE_WHITE_KINGSIDE) { putchar('K'); } 51 | if (g.castle_flags & CASTLE_WHITE_QUEENSIDE) { putchar('Q'); } 52 | if (g.castle_flags & CASTLE_BLACK_KINGSIDE) { putchar('k'); } 53 | if (g.castle_flags & CASTLE_BLACK_QUEENSIDE) { putchar('q'); } 54 | } 55 | putchar('\n'); 56 | } 57 | 58 | uint64_t n; 59 | 60 | void tick_counter(gamestate x, move m, int d) { 61 | if (d == 1) 62 | n++; 63 | } 64 | 65 | void walk_game_tree(gamestate init, int depth, ft_action f) 66 | { 67 | if (depth <= 0) { 68 | return; 69 | } else { 70 | iterator i = mkLegalIterator(init); 71 | while (! is_iterator_finished(i)) { 72 | move m = dereference_iterator(i); 73 | gamestate g = apply_move(init, m); 74 | 75 | f(init, m, depth); 76 | walk_game_tree(g, depth-1, f); 77 | iterator i2 = advance_iterator_legal(init, i); 78 | if (! iter_lt(i2, i)) { 79 | printf("%lu\n", n); 80 | print_iterator(i); 81 | print_iterator(i2); 82 | throw "derp"; 83 | } 84 | i = i2; 85 | } 86 | } 87 | } 88 | 89 | void print_gamestate_action(gamestate g, move m, int d) { print_move_stdout(m); putchar('\n');} 90 | 91 | void print_moves(gamestate g) 92 | { 93 | walk_game_tree(g, 1, print_gamestate_action); 94 | } 95 | 96 | void assert_equal_string(const char* message, const char* x, const char *y) 97 | { 98 | const char* orig_x = x, *orig_y = y; 99 | while (*x) { 100 | if (*x != *y) 101 | goto error; 102 | if (*x == 0) 103 | break; 104 | x++; 105 | y++; 106 | } 107 | return; 108 | error: 109 | printf("ASSERTION FAILURE: %s\n", message); 110 | printf("== expected: %s\n", orig_x); 111 | printf("== actual: %s\n", orig_y); 112 | throw "derp"; 113 | } 114 | 115 | void assert_equal_bb(const char* message, uint64_t x, uint64_t y) 116 | { 117 | if (x != y) { 118 | printf("ASSERTION FAILURE: %s\n", message); 119 | printf("== expected\n"); 120 | print_bitboard(x); 121 | printf("== actual\n"); 122 | print_bitboard(y); 123 | throw "derp"; 124 | } 125 | } 126 | void assert_equal_int(const char* message, int x, int y) 127 | { 128 | if (x != y) { 129 | printf("ASSERTION_FAILURE: %s\n", message); 130 | printf("%d != %d", x,y); 131 | throw "derp"; 132 | } 133 | } 134 | 135 | void assert_equal_u64(const char* message, uint64_t x, uint64_t y) 136 | { 137 | if (x != y) { 138 | printf("ASSERTION_FAILURE: %s\n", message); 139 | printf("%lu != %lu", x,y); 140 | throw "derp"; 141 | } 142 | } 143 | 144 | void assert(const char* message, bool x) 145 | { 146 | if (! x) { 147 | printf("ASSERTION_FAILURE: %s\n", message); 148 | throw "derp"; 149 | } 150 | } 151 | 152 | void test_ray() 153 | { 154 | // Base rays 155 | { 156 | uint64_t center = mkPosition(3,3); 157 | uint64_t nw_ray = 158 | bit(mkPosition(0,6)) | 159 | bit(mkPosition(1,5)) | 160 | bit(mkPosition(2,4)); 161 | uint64_t n_ray = 162 | bit(mkPosition(3,4)) | 163 | bit(mkPosition(3,5)) | 164 | bit(mkPosition(3,6)) | 165 | bit(mkPosition(3,7)); 166 | uint64_t ne_ray = 167 | bit(mkPosition(4,4)) | 168 | bit(mkPosition(5,5)) | 169 | bit(mkPosition(6,6)) | 170 | bit(mkPosition(7,7)); 171 | uint64_t e_ray = 172 | bit(mkPosition(4,3)) | 173 | bit(mkPosition(5,3)) | 174 | bit(mkPosition(6,3)) | 175 | bit(mkPosition(7,3)); 176 | uint64_t se_ray = 177 | bit(mkPosition(4,2)) | 178 | bit(mkPosition(5,1)) | 179 | bit(mkPosition(6,0)); 180 | uint64_t s_ray = 181 | bit(mkPosition(3,2)) | 182 | bit(mkPosition(3,1)) | 183 | bit(mkPosition(3,0)); 184 | uint64_t sw_ray = 185 | bit(mkPosition(2,2)) | 186 | bit(mkPosition(1,1)) | 187 | bit(mkPosition(0,0)); 188 | uint64_t w_ray = 189 | bit(mkPosition(2,3)) | 190 | bit(mkPosition(1,3))| 191 | bit(mkPosition(0,3)); 192 | 193 | assert_equal_bb("nw", nw_ray, mkRay(center, DIRECTION_NORTHWEST)); 194 | assert_equal_bb("n", n_ray, mkRay(center, DIRECTION_NORTH)); 195 | assert_equal_bb("ne", ne_ray, mkRay(center, DIRECTION_NORTHEAST)); 196 | assert_equal_bb("e", e_ray, mkRay(center, DIRECTION_EAST)); 197 | assert_equal_bb("se", se_ray, mkRay(center, DIRECTION_SOUTHEAST)); 198 | assert_equal_bb("s", s_ray, mkRay(center, DIRECTION_SOUTH)); 199 | assert_equal_bb("sw", sw_ray, mkRay(center, DIRECTION_SOUTHWEST)); 200 | assert_equal_bb("w", w_ray, mkRay(center, DIRECTION_WEST)); 201 | } 202 | // Rays with blockers 203 | { 204 | uint64_t center = mkPosition(3,3); 205 | // W 206 | { 207 | gamestate g = zerostate(); 208 | g.pawns_bb = 209 | bit(mkPosition(1,3)) | 210 | bit(mkPosition(0,3)); 211 | uint64_t expected = 212 | bit(mkPosition(2,3)) | 213 | bit(mkPosition(1,3)); 214 | /* printf("== expected:\n"); print_bitboard(expected); printf("\n"); */ 215 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_WEST); 216 | /* printf("== actual:\n"); print_bitboard(actual); printf("\n"); */ 217 | /* uint64_t base_ray = mkRay(center, DIRECTION_WEST); */ 218 | /* printf("== base_ray:\n"); print_bitboard(base_ray); printf("\n"); */ 219 | /* uint64_t blockers = base_ray & all_pieces(g); */ 220 | /* printf("== blockers:\n"); print_bitboard(blockers); printf("\n"); */ 221 | /* int blocker = closest_blocker(blockers, DIRECTION_WEST); */ 222 | /* printf("== blocker: "); print_pos(blocker); printf("\n"); */ 223 | /* uint64_t blocker_ray = mkRay(blocker, DIRECTION_WEST); */ 224 | /* printf("== blocker_ray:\n"); print_bitboard(blocker_ray); */ 225 | /* uint64_t movable_squares_without_capture = base_ray ^ blocker_ray ^ bit(blocker); */ 226 | /* printf("== movable_squares_without_capture\n"); print_bitboard(movable_squares_without_capture); printf("\n"); */ 227 | 228 | assert_equal_int("w_blocker", mkPosition(1,3), closest_blocker(g.pawns_bb, DIRECTION_WEST)); 229 | assert_equal_bb("w", expected, actual); 230 | } 231 | // NW 232 | { 233 | gamestate g = zerostate(); 234 | g.pawns_bb = 235 | bit(mkPosition(1,5)) | 236 | bit(mkPosition(0,6)); 237 | uint64_t expected = 238 | bit(mkPosition(2,4)) | 239 | bit(mkPosition(1,5)); 240 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_NORTHWEST); 241 | assert_equal_int("nw_blocker", mkPosition(1,5), closest_blocker(g.pawns_bb, DIRECTION_NORTHWEST)); 242 | assert_equal_bb("nw", expected, actual); 243 | } 244 | // N 245 | { 246 | gamestate g = zerostate(); 247 | g.pawns_bb = 248 | bit(mkPosition(3,6)) | 249 | bit(mkPosition(3,7)); 250 | uint64_t expected = 251 | bit(mkPosition(3,4)) | 252 | bit(mkPosition(3,5)) | 253 | bit(mkPosition(3,6)); 254 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_NORTH); 255 | assert_equal_int("n_blocker", mkPosition(3,6), closest_blocker(g.pawns_bb, DIRECTION_NORTH)); 256 | assert_equal_bb("n", expected, actual); 257 | } 258 | // NE 259 | { 260 | gamestate g = zerostate(); 261 | g.pawns_bb = 262 | bit(mkPosition(6,6)) | 263 | bit(mkPosition(7,7)); 264 | uint64_t expected = 265 | bit(mkPosition(4,4)) | 266 | bit(mkPosition(5,5)) | 267 | bit(mkPosition(6,6)); 268 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_NORTHEAST); 269 | assert_equal_int("ne_blocker", mkPosition(6,6), closest_blocker(g.pawns_bb, DIRECTION_NORTHEAST)); 270 | assert_equal_bb("ne", expected, actual); 271 | } 272 | // NE 2 273 | { 274 | uint64_t center = mkPosition(0,2); 275 | gamestate g = zerostate(); 276 | g.pawns_bb = 277 | bit(mkPosition(4,6)) | 278 | bit(mkPosition(5,7)); 279 | uint64_t expected = 280 | bit(mkPosition(1,3)) | 281 | bit(mkPosition(2,4)) | 282 | bit(mkPosition(3,5)) | 283 | bit(mkPosition(4,6)); 284 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_NORTHEAST); 285 | assert_equal_bb("ne_2", expected, actual); 286 | } 287 | // NE 3 288 | { 289 | uint64_t bb = bit(mkPosition(4,6)) | bit(mkPosition(5,7)); 290 | int i = closest_blocker(bb, DIRECTION_NORTHEAST); 291 | assert_equal_int("ne_3", mkPosition(4,6), i); 292 | } 293 | // E 294 | { 295 | gamestate g = zerostate(); 296 | g.pawns_bb = 297 | bit(mkPosition(6,3)) | 298 | bit(mkPosition(7,3)); 299 | uint64_t expected = 300 | bit(mkPosition(4,3)) | 301 | bit(mkPosition(5,3)) | 302 | bit(mkPosition(6,3)); 303 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_EAST); 304 | assert_equal_int("e_blocker", mkPosition(6,3), closest_blocker(g.pawns_bb, DIRECTION_EAST)); 305 | assert_equal_bb("e", expected, actual); 306 | } 307 | // SE 308 | { 309 | gamestate g = zerostate(); 310 | g.pawns_bb = 311 | bit(mkPosition(5,1)) | 312 | bit(mkPosition(6,0)); 313 | uint64_t expected = 314 | bit(mkPosition(4,2)) | 315 | bit(mkPosition(5,1)); 316 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_SOUTHEAST); 317 | assert_equal_int("se_blocker", mkPosition(5,1), closest_blocker(g.pawns_bb, DIRECTION_SOUTHEAST)); 318 | assert_equal_bb("se", expected, actual); 319 | } 320 | // S 321 | { 322 | gamestate g = zerostate(); 323 | g.pawns_bb = 324 | bit(mkPosition(3,1)) | 325 | bit(mkPosition(3,0)); 326 | uint64_t expected = 327 | bit(mkPosition(3,2)) | 328 | bit(mkPosition(3,1)); 329 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_SOUTH); 330 | assert_equal_int("s_blocker", mkPosition(3,1), closest_blocker(g.pawns_bb, DIRECTION_SOUTH)); 331 | assert_equal_bb("s", expected, actual); 332 | } 333 | // SW 334 | { 335 | gamestate g = zerostate(); 336 | g.pawns_bb = 337 | bit(mkPosition(1,1)) | 338 | bit(mkPosition(0,0)); 339 | uint64_t expected = 340 | bit(mkPosition(2,2)) | 341 | bit(mkPosition(1,1)); 342 | uint64_t actual = shoot_ray_until_blocker(g, center, DIRECTION_SOUTHWEST); 343 | assert_equal_int("sw_blocker", mkPosition(1,1), closest_blocker(g.pawns_bb, DIRECTION_SOUTHWEST)); 344 | assert_equal_bb("sw", expected, actual); 345 | } 346 | } 347 | } 348 | 349 | void test_rook() 350 | { 351 | // Rook in middle 352 | { 353 | uint64_t center = mkPosition(3,3); 354 | gamestate g = zerostate(); 355 | g.rooks_bb = bit(center); 356 | g.current_piece_bb = g.rooks_bb; 357 | 358 | uint64_t expected = clear_bit(mkRank(3) | mkFile(3), center); 359 | uint64_t actual = valid_rook_moves(g, center); 360 | assert_equal_bb("test_rook_middle", expected, actual); 361 | } 362 | // Rook in corner 363 | { 364 | uint64_t center = mkPosition(0,0); 365 | gamestate g = zerostate(); 366 | g.rooks_bb = bit(center); 367 | g.current_piece_bb = g.rooks_bb; 368 | 369 | uint64_t expected = clear_bit(mkRank(0) | mkFile(0), center); 370 | uint64_t actual = valid_rook_moves(g, center); 371 | assert_equal_bb("test_rook_corner", expected, actual); 372 | } 373 | // Rook blocked in left corner 374 | { 375 | uint64_t center = mkPosition(0,0); 376 | gamestate g = zerostate(); 377 | g.rooks_bb = bit(center) | bit(mkPosition(0,1)) | bit(mkPosition(1,0)); 378 | g.current_piece_bb = g.rooks_bb; 379 | 380 | assert_equal_bb("test_rook_blocked_1", 0, valid_rook_moves(g, center)); 381 | } 382 | // Rook blocked in right corner 383 | { 384 | uint64_t center = mkPosition(7,0); 385 | gamestate g = zerostate(); 386 | g.rooks_bb = bit(center) | bit(mkPosition(7,1)) | bit(mkPosition(6,0)); 387 | g.current_piece_bb = g.rooks_bb; 388 | 389 | assert_equal_bb("test_rook_blocked_2", 0, valid_rook_moves(g, center)); 390 | } 391 | } 392 | 393 | void test_pawn() 394 | { 395 | // Left edge 396 | { 397 | uint64_t center = mkPosition(0,1); 398 | gamestate g = zerostate(); 399 | g.pawns_bb = bit(center); 400 | g.current_piece_bb = g.pawns_bb; 401 | 402 | uint64_t expected = bit(mkPosition(0,2)) | bit(mkPosition(0,3)); 403 | uint64_t actual = valid_pawn_moves(g, center); 404 | assert_equal_bb("test_pawn_1", expected, actual); 405 | 406 | } 407 | // Right edge 408 | { 409 | uint64_t center = mkPosition(7,1); 410 | gamestate g = zerostate(); 411 | g.pawns_bb = bit(center); 412 | g.current_piece_bb = g.pawns_bb; 413 | 414 | uint64_t expected = bit(mkPosition(7,2)) | bit(mkPosition(7,3)); 415 | uint64_t actual = valid_pawn_moves(g, center); 416 | assert_equal_bb("test_pawn_2", expected, actual); 417 | } 418 | // Middle 419 | { 420 | uint64_t center = mkPosition(3,1); 421 | gamestate g = zerostate(); 422 | g.pawns_bb = bit(center); 423 | g.current_piece_bb = g.pawns_bb; 424 | 425 | uint64_t expected = bit(mkPosition(3,2)) | bit(mkPosition(3,3)); 426 | uint64_t actual = valid_pawn_moves(g, center); 427 | assert_equal_bb("test_pawn_3", expected, actual); 428 | } 429 | // Capture 430 | { 431 | uint64_t center = mkPosition(7,1); 432 | gamestate g = zerostate(); 433 | g.pawns_bb = bit(center); 434 | g.current_piece_bb = g.pawns_bb; 435 | g.pawns_bb |= bit(move_direction(center, DIRECTION_NORTHWEST)); 436 | 437 | uint64_t expected = bit(mkPosition(7,2)) | bit(mkPosition(7,3)) | bit(mkPosition(6,2)); 438 | uint64_t actual = valid_pawn_moves(g, center); 439 | assert_equal_bb("test_pawn_4", expected, actual); 440 | } 441 | // Blocked by another piece 442 | { 443 | uint64_t center = mkPosition(0,1); 444 | gamestate g = zerostate(); 445 | g.pawns_bb = bit(center) | bit(center + RANK); 446 | g.current_piece_bb = g.pawns_bb; 447 | 448 | uint64_t expected = 0; 449 | uint64_t actual = valid_pawn_moves(g, center); 450 | assert_equal_bb("test_pawn_5", expected, actual); 451 | } 452 | // Blocked by another piece when double-jumping 453 | { 454 | uint64_t center = mkPosition(0,1); 455 | gamestate g = zerostate(); 456 | g.pawns_bb = bit(center); 457 | g.current_piece_bb = g.pawns_bb; 458 | g.pawns_bb |= bit(mkPosition(0,3)); 459 | 460 | uint64_t expected = bit(mkPosition(0,2)); 461 | uint64_t actual = valid_pawn_moves(g, center); 462 | assert_equal_bb("test_pawn_6", expected, actual); 463 | } 464 | // En Passant 465 | { 466 | gamestate g = zerostate(); 467 | g.pawns_bb = 468 | bit(mkPosition(0,1)) | 469 | bit(mkPosition(1,3)); 470 | g.current_piece_bb = bit(mkPosition(0,1)); 471 | 472 | iterator i = mkIterator(g); 473 | { 474 | uint64_t expected = 475 | bit(mkPosition(0,2)) | 476 | bit(mkPosition(0,3)); 477 | assert_equal_bb("test_pawn_en_passant_1", expected, i.current_piece_bb); 478 | } 479 | // Double jump allows en passant 480 | move m; m.from = mkPosition(0,1); m.to = mkPosition(0,3); 481 | g = apply_move(g, m); 482 | i = mkIterator(g); 483 | { 484 | uint64_t expected = 485 | bit(mkPosition(0,5)) | 486 | bit(mkPosition(1,5)); 487 | assert_equal_int("test_pawn_en_passant_target", mkPosition(0,5), g.en_passant_sq); 488 | assert_equal_bb("test_pawn_en_passant_2", expected, i.current_piece_bb); 489 | } 490 | // The actual capture 491 | move m2; m2.from = mkPosition(1,3); m2.to = mkPosition(0,2); 492 | g = apply_move(g, swap_move(m2)); 493 | { 494 | assert_equal_int("test_pawn_en_passant_target_2", POSITION_INVALID, g.en_passant_sq); 495 | assert_equal_bb("test_pawn_en_passant_3", bit(mkPosition(0,2)), g.pawns_bb); 496 | } 497 | } 498 | } 499 | 500 | void test_iterator() 501 | { 502 | // Piece has valid moves 503 | { 504 | uint64_t center = mkPosition(0,0); 505 | gamestate g = zerostate(); 506 | g.rooks_bb = bit(center); 507 | g.current_piece_bb = g.rooks_bb; 508 | 509 | uint64_t expected = 510 | mkRay(center, DIRECTION_NORTH) | 511 | mkRay(center, DIRECTION_EAST); 512 | iterator i = mkIterator(g); 513 | uint64_t actual = i.current_piece_bb; 514 | assert_equal_bb("test_iterator_1", expected, actual); 515 | } 516 | // Piece has no valid moves; skip to next 517 | { 518 | uint64_t center = mkPosition(0,0); 519 | gamestate g = zerostate(); 520 | g.pawns_bb = bit(mkPosition(0,1)); 521 | g.rooks_bb = bit(center); 522 | g.knights_bb = bit(mkPosition(1,0)); 523 | g.current_piece_bb = all_pieces(g); 524 | 525 | iterator i = mkIterator(g); 526 | assert_equal_bb("test_iterator_2_rooks", 0, i.rooks_bb); 527 | assert_equal_bb("test_iterator_2_knights", bit(mkPosition(1,0)), i.knights_bb); 528 | uint64_t expected = 529 | bit(mkPosition(0,2)) | 530 | bit(mkPosition(2,2)) | 531 | bit(mkPosition(3,1)); 532 | assert_equal_bb("test_iterator_2_knight_moves", expected, i.current_piece_bb); 533 | } 534 | // Two pieces have no valid moves; skip to next 535 | { 536 | gamestate g = zerostate(); 537 | g.pawns_bb = 538 | bit(mkPosition(0,1)) | 539 | bit(mkPosition(7,1)); 540 | g.rooks_bb = 541 | bit(mkPosition(0,0)) | 542 | bit(mkPosition(7,0)); 543 | g.knights_bb = 544 | bit(mkPosition(1,0)) | 545 | bit(mkPosition(6,0)); 546 | g.current_piece_bb = all_pieces(g); 547 | iterator i = mkIterator(g); 548 | assert_equal_bb("test_iterator_3_rooks", 0, i.rooks_bb); 549 | assert_equal_bb("test_iterator_3_knights", bit(mkPosition(1,0)) | bit(mkPosition(6,0)), i.knights_bb); 550 | uint64_t expected = valid_knight_moves(g, mkPosition(1,0)); 551 | assert_equal_bb("test_iterator_3_knight_moves", expected, i.current_piece_bb); 552 | 553 | } 554 | // Empty iterator is finished 555 | { 556 | gamestate g = zerostate(); 557 | iterator i = zerostate(); 558 | assert("test_iterator_empty_1", is_iterator_finished(i)); 559 | iterator j = advance_iterator(g, i); 560 | assert("test_iterator_empty_2", is_iterator_finished(j)); 561 | } 562 | } 563 | 564 | void test_knight() 565 | { 566 | // Knight in left bottom 567 | { 568 | uint64_t center = mkPosition(1,0); 569 | gamestate g = zerostate(); 570 | g.knights_bb = bit(center); 571 | g.current_piece_bb = g.knights_bb; 572 | 573 | uint64_t expected = 574 | bit(mkPosition(0,2)) | 575 | bit(mkPosition(2,2)) | 576 | bit(mkPosition(3,1)); 577 | uint64_t actual = valid_knight_moves(g, center); 578 | assert_equal_bb("test_knight_1", expected, actual); 579 | } 580 | // Knight in right bottom 581 | { 582 | uint64_t center = mkPosition(6,0); 583 | gamestate g = zerostate(); 584 | g.knights_bb = bit(center); 585 | g.current_piece_bb = g.knights_bb; 586 | 587 | uint64_t expected = 588 | bit(mkPosition(7,2)) | 589 | bit(mkPosition(5,2)) | 590 | bit(mkPosition(4,1)); 591 | uint64_t actual = valid_knight_moves(g, center); 592 | assert_equal_bb("test_knight_2", expected, actual); 593 | } 594 | } 595 | 596 | void test_king() 597 | { 598 | // King in middle 599 | { 600 | uint64_t center = mkPosition(3,3); 601 | gamestate g = zerostate(); 602 | g.kings_bb = bit(center); 603 | g.current_piece_bb = g.kings_bb; 604 | 605 | uint64_t expected = 606 | bit(mkPosition(4,3)) | 607 | bit(mkPosition(4,4)) | 608 | bit(mkPosition(3,4)) | 609 | bit(mkPosition(2,4)) | 610 | bit(mkPosition(2,3)) | 611 | bit(mkPosition(2,2)) | 612 | bit(mkPosition(3,2)) | 613 | bit(mkPosition(4,2)); 614 | uint64_t actual = valid_king_moves(g, center); 615 | assert_equal_bb("test_king_1", expected, actual); 616 | } 617 | // King blocked on 3 sides in left corner 618 | { 619 | uint64_t center = mkPosition(0,0); 620 | gamestate g = zerostate(); 621 | g.kings_bb = bit(center); 622 | g.pawns_bb = 623 | bit(mkPosition(1,0)) | 624 | bit(mkPosition(1,1)) | 625 | bit(mkPosition(0,1)); 626 | g.current_piece_bb = all_pieces(g); 627 | 628 | uint64_t expected = 0; 629 | uint64_t actual = valid_king_moves(g, center); 630 | assert_equal_bb("test_king_2", expected, actual); 631 | } 632 | } 633 | 634 | void test_bishop() 635 | { 636 | // Bishop southwest blocker 637 | { 638 | gamestate g = zerostate(); 639 | g.pawns_bb = bit(mkPosition(3,1)); 640 | g.kings_bb = bit(mkPosition(2,0)); 641 | g.current_piece_bb = bit(mkPosition(7,5)); 642 | g.bishops_bb = bit(mkPosition(7,5)); 643 | 644 | { 645 | uint64_t expected = 646 | bit(mkPosition(6,6)) | 647 | bit(mkPosition(5,7)) | 648 | bit(mkPosition(6,4)) | 649 | bit(mkPosition(5,3)) | 650 | bit(mkPosition(4,2)) | 651 | bit(mkPosition(3,1)); 652 | uint64_t actual = valid_bishop_moves(g, mkPosition(7,5)); 653 | assert_equal_bb("test_bishop_1", expected, actual); 654 | } 655 | // King not in check from bishop 656 | g.current_piece_bb ^= all_pieces(g); 657 | assert("test_bishop_1_check", ! is_in_check(g)); 658 | } 659 | // Bishop northeast blocker 660 | { 661 | gamestate g = zerostate(); 662 | g.pawns_bb = bit(mkPosition(3,1)); 663 | g.kings_bb = bit(mkPosition(2,0)); 664 | g.current_piece_bb = all_pieces(g); 665 | g.bishops_bb = bit(mkPosition(7,5)); 666 | { 667 | uint64_t expected = 668 | bit(mkPosition(6,6)) | 669 | bit(mkPosition(5,7)) | 670 | bit(mkPosition(6,4)) | 671 | bit(mkPosition(5,3)) | 672 | bit(mkPosition(4,2)); 673 | uint64_t actual = valid_bishop_moves(g, mkPosition(7,5)); 674 | assert_equal_bb("test_bishop_2", expected, actual); 675 | } 676 | // King not in check from bishop 677 | assert("test_bishop_2_check", ! is_in_check(g)); 678 | } 679 | } 680 | 681 | void test_apply_move() 682 | { 683 | // Knight in middle 684 | { 685 | uint64_t center = mkPosition(3,3); 686 | gamestate g = zerostate(); 687 | g.knights_bb = bit(center); 688 | g.current_piece_bb = g.knights_bb; 689 | 690 | iterator i = mkIterator(g); 691 | move m = dereference_iterator(i); 692 | assert_equal_int("test_apply_move_from", center, m.from); 693 | assert_equal_int("test_apply_move_to", mkPosition(2,1), m.to); 694 | gamestate g2 = swap_board(apply_move(g, m)); 695 | 696 | assert_equal_bb("test_apply_move", bit(mkPosition(2,1)), g2.knights_bb); 697 | } 698 | // Doesn't affect other pieces 699 | { 700 | uint64_t center = mkPosition(3,3); 701 | gamestate g = zerostate(); 702 | g.knights_bb = bit(center); 703 | g.current_piece_bb = g.knights_bb; 704 | g.knights_bb |= 705 | bit(mkPosition(1,0)) | 706 | bit(mkPosition(6,0)); 707 | 708 | iterator i = mkIterator(g); 709 | move m = dereference_iterator(i); 710 | assert_equal_int("test_apply_move_from", center, m.from); 711 | assert_equal_int("test_apply_move_to", mkPosition(2,1), m.to); 712 | gamestate g2 = swap_board(apply_move(g, m)); 713 | 714 | uint64_t expected = bit(m.to) | bit(mkPosition(1,0)) | bit(mkPosition(6,0)); 715 | assert_equal_bb("test_apply_move_2", expected, g2.knights_bb); 716 | } 717 | } 718 | 719 | void test_check() 720 | { 721 | // King in check 1 722 | { 723 | uint64_t center = mkPosition(3,3); 724 | gamestate g = zerostate(); 725 | g.kings_bb = bit(center); 726 | g.rooks_bb = bit(center+2); 727 | g.current_player_bb = g.kings_bb; 728 | 729 | assert("test_check_1", is_in_check(g)); 730 | } 731 | // King in check 2 732 | { 733 | uint64_t center = mkPosition(3,3); 734 | gamestate g = zerostate(); 735 | g.kings_bb = bit(center); 736 | g.rooks_bb = bit(center-2*RANK); 737 | g.current_player_bb = g.kings_bb; 738 | 739 | assert("test_check_2", is_in_check(g)); 740 | } 741 | // King blocked by rooks 742 | { 743 | uint64_t center = mkPosition(3,3); 744 | gamestate g = zerostate(); 745 | g.kings_bb = bit(center); 746 | g.rooks_bb = 747 | bit(mkPosition(0,4)) | 748 | bit(mkPosition(0,2)) | 749 | bit(mkPosition(2,0)); 750 | //bit(mkPosition(0,2)); 751 | g.current_player_bb = g.kings_bb; 752 | assert_equal_int("test_check_3", 1, num_legal_moves(g)); 753 | } 754 | // King can safely move to a square protected by own unit. 755 | { 756 | gamestate g = zerostate(); 757 | g.pawns_bb = 758 | bit(mkPosition(3,1)) | 759 | bit(mkPosition(4,0)) | 760 | bit(mkPosition(4,1)) | 761 | bit(mkPosition(2,1)); 762 | g.kings_bb = bit(mkPosition(3,0)); 763 | g.bishops_bb = 764 | bit(mkPosition(0,2)) | 765 | bit(mkPosition(0,5)); 766 | g.knights_bb = 767 | bit(mkPosition(1,0)) | 768 | bit(mkPosition(6,0)); 769 | g.current_piece_bb = all_pieces(g); 770 | g.bishops_bb |= bit(mkPosition(7,5)); 771 | { 772 | uint64_t expected = 773 | bit(mkPosition(6,6)) | 774 | bit(mkPosition(5,7)) | 775 | bit(mkPosition(6,4)) | 776 | bit(mkPosition(5,3)) | 777 | bit(mkPosition(4,2)); 778 | uint64_t actual = valid_bishop_moves(g, mkPosition(7,5)); 779 | assert_equal_bb("test_check_4_bishop", expected, actual); 780 | } 781 | // King not in check from bishop 782 | assert("test_check_4_check", ! is_in_check(g)); 783 | { 784 | int from = mkPosition(3,0); 785 | int target = mkPosition(2,0); 786 | uint64_t expected = bit(target); 787 | uint64_t actual = piece_legal_movepoints(g, from); 788 | assert_equal_bb("test_check_4_king_valid", bit(target), valid_king_moves(g, from)); 789 | iterator i = zerostate(); 790 | int piece = get_piece(g, from); 791 | i = set_piece_bb(i, piece, bit(from)); 792 | i = reset_iterator_moves(g,i); 793 | i = legalize(g,i); 794 | 795 | assert_equal_bb("test_check_4_next", bit(target), i.current_piece_bb); 796 | assert_equal_bb("test_check_4_moves", expected, actual); 797 | } 798 | } 799 | } 800 | 801 | void test_castling() 802 | { 803 | // Kingside castle 1 804 | { 805 | gamestate g = zerostate(); 806 | g.kings_bb = bit(mkPosition(4,0)); 807 | g.rooks_bb = bit(mkPosition(7,0)); 808 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 809 | g.current_player_bb = all_pieces(g); 810 | 811 | uint64_t expected = 812 | bit(mkPosition(3,0)) | 813 | bit(mkPosition(3,1)) | 814 | bit(mkPosition(4,1)) | 815 | bit(mkPosition(5,1)) | 816 | bit(mkPosition(5,0)) | 817 | bit(mkPosition(6,0)); 818 | uint64_t actual = valid_king_moves(g, mkPosition(4,0)); 819 | assert_equal_bb("test_castling_1_moves", expected, actual); 820 | move m; m.from = mkPosition(4,0); m.to = CASTLE_KINGSIDE_KPOS; 821 | gamestate g2 = swap_board(apply_move(g, m)); 822 | assert_equal_bb("test_castling_1_king", bit(CASTLE_KINGSIDE_KPOS), g2.kings_bb); 823 | assert_equal_bb("test_castling_1_rook", bit(CASTLE_KINGSIDE_RPOS), g2.rooks_bb); 824 | assert_equal_u64("test_castling_1_flags", 0, g2.castle_flags); 825 | } 826 | // Queenside castle 1 827 | { 828 | gamestate g = zerostate(); 829 | g.kings_bb = bit(mkPosition(4,0)); 830 | g.rooks_bb = bit(mkPosition(0,0)); 831 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 832 | g.current_player_bb = all_pieces(g); 833 | 834 | uint64_t expected = 835 | bit(mkPosition(3,0)) | 836 | bit(mkPosition(3,1)) | 837 | bit(mkPosition(4,1)) | 838 | bit(mkPosition(5,1)) | 839 | bit(mkPosition(5,0)) | 840 | bit(mkPosition(2,0)); 841 | uint64_t actual = valid_king_moves(g, mkPosition(4,0)); 842 | assert_equal_bb("test_castling_2_moves", expected, actual); 843 | move m; m.from = mkPosition(4,0); m.to = mkPosition(2,0); 844 | gamestate g2 = swap_board(apply_move(g, m)); 845 | assert_equal_bb("test_castling_2_king", bit(mkPosition(2,0)), g2.kings_bb); 846 | assert_equal_bb("test_castling_2_rook", bit(mkPosition(3,0)), g2.rooks_bb); 847 | assert_equal_u64("test_castling_2_flags", 0, g2.castle_flags); 848 | } 849 | // Kingside castle blocked by check 1 850 | { 851 | gamestate g = zerostate(); 852 | g.kings_bb = bit(mkPosition(4,0)); 853 | g.rooks_bb = bit(mkPosition(7,0)); 854 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 855 | g.current_player_bb = all_pieces(g); 856 | g.rooks_bb |= bit(mkPosition(5,7)); 857 | 858 | uint64_t expected = 859 | bit(mkPosition(3,0)) | 860 | bit(mkPosition(3,1)) | 861 | bit(mkPosition(4,1)); 862 | uint64_t actual = piece_legal_movepoints(g, mkPosition(4,0)); 863 | move not_castle; not_castle.from = mkPosition(4,0); not_castle.to = mkPosition(4,1); 864 | move castle_kingside; castle_kingside.from = mkPosition(4,0); castle_kingside.to = mkPosition(6,0); 865 | assert("test_castling_3_not_kingside_1", ! is_kingside_castle(g, not_castle)); 866 | assert("test_castling_3_not_kingside_2", ! is_queenside_castle(g, not_castle)); 867 | assert("test_castling_3_not_kingside_3", ! results_in_check(g, not_castle)); 868 | assert("test_castling_3_not_kingside_4", is_legal(g, not_castle)); 869 | assert("test_castling_3_illegal", ! is_legal(g, castle_kingside)); 870 | assert_equal_bb("test_castling_3_moves", expected, actual); 871 | } 872 | // Queenside castle blocked by check 1 873 | { 874 | gamestate g = zerostate(); 875 | g.kings_bb = bit(mkPosition(4,0)); 876 | g.rooks_bb = bit(mkPosition(0,0)); 877 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 878 | g.current_player_bb = all_pieces(g); 879 | g.rooks_bb |= bit(mkPosition(3,7)); 880 | 881 | uint64_t expected = 882 | bit(mkPosition(4,1)) | 883 | bit(mkPosition(5,1)) | 884 | bit(mkPosition(5,0)); 885 | uint64_t actual = piece_legal_movepoints(g, mkPosition(4,0)); 886 | assert_equal_bb("test_castling_4_moves", expected, actual); 887 | } 888 | // Kingside castle blocked by check 2 889 | { 890 | gamestate g = zerostate(); 891 | g.kings_bb = bit(mkPosition(4,0)); 892 | g.rooks_bb = bit(mkPosition(7,0)); 893 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 894 | g.current_player_bb = all_pieces(g); 895 | g.rooks_bb |= bit(mkPosition(4,7)); 896 | 897 | uint64_t expected = 898 | bit(mkPosition(3,0)) | 899 | bit(mkPosition(3,1)) | 900 | bit(mkPosition(5,1)) | 901 | bit(mkPosition(5,0)); 902 | uint64_t actual = piece_legal_movepoints(g, mkPosition(4,0)); 903 | assert_equal_bb("test_castling_5_moves", expected, actual); 904 | } 905 | // Queenside castle blocked by check 2 906 | { 907 | gamestate g = zerostate(); 908 | g.kings_bb = bit(mkPosition(4,0)); 909 | g.rooks_bb = bit(mkPosition(0,0)); 910 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 911 | g.current_player_bb = all_pieces(g); 912 | g.rooks_bb |= bit(mkPosition(4,7)); 913 | 914 | uint64_t expected = 915 | bit(mkPosition(3,0)) | 916 | bit(mkPosition(3,1)) | 917 | bit(mkPosition(5,1)) | 918 | bit(mkPosition(5,0)); 919 | uint64_t actual = piece_legal_movepoints(g, mkPosition(4,0)); 920 | assert_equal_bb("test_castling_6_moves", expected, actual); 921 | } 922 | // Kingside castle blocked by unit 923 | { 924 | gamestate g = zerostate(); 925 | g.kings_bb = bit(mkPosition(4,0)); 926 | g.rooks_bb = bit(mkPosition(7,0)); 927 | g.bishops_bb |= bit(mkPosition(5,0)); 928 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 929 | g.current_player_bb = all_pieces(g); 930 | 931 | uint64_t expected = 932 | bit(mkPosition(3,0)) | 933 | bit(mkPosition(3,1)) | 934 | bit(mkPosition(4,1)) | 935 | bit(mkPosition(5,1)); 936 | uint64_t actual = valid_king_moves(g, mkPosition(4,0)); 937 | assert_equal_bb("test_castling_7_moves", expected, actual); 938 | } 939 | // Queenside castle blocked by unit 940 | { 941 | gamestate g = zerostate(); 942 | g.kings_bb = bit(mkPosition(4,0)); 943 | g.rooks_bb = bit(mkPosition(0,0)); 944 | g.bishops_bb = bit(mkPosition(3,0)); 945 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 946 | g.current_player_bb = all_pieces(g); 947 | 948 | uint64_t expected = 949 | bit(mkPosition(3,1)) | 950 | bit(mkPosition(4,1)) | 951 | bit(mkPosition(5,1)) | 952 | bit(mkPosition(5,0)); 953 | uint64_t actual = valid_king_moves(g, mkPosition(4,0)); 954 | assert_equal_bb("test_castling_8_moves", expected, actual); 955 | } 956 | // Castle flags swap 957 | { 958 | { 959 | gamestate g = zerostate(); 960 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 961 | g = swap_board(g); 962 | assert_equal_u64("test_castling_9_flag_wk", CASTLE_BLACK_KINGSIDE, g.castle_flags); 963 | } 964 | { 965 | gamestate g = zerostate(); 966 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 967 | g = swap_board(g); 968 | assert_equal_u64("test_castling_9_flag_wk", CASTLE_BLACK_QUEENSIDE, g.castle_flags); 969 | } 970 | { 971 | gamestate g = zerostate(); 972 | g.castle_flags = CASTLE_BLACK_KINGSIDE; 973 | g = swap_board(g); 974 | assert_equal_u64("test_castling_9_flag_wk", CASTLE_WHITE_KINGSIDE, g.castle_flags); 975 | } 976 | { 977 | gamestate g = zerostate(); 978 | g.castle_flags = CASTLE_BLACK_QUEENSIDE; 979 | g = swap_board(g); 980 | assert_equal_u64("test_castling_9_flag_wk", CASTLE_WHITE_QUEENSIDE, g.castle_flags); 981 | } 982 | } 983 | // Moving kingside rook deletes flag 984 | { 985 | gamestate g = zerostate(); 986 | g.rooks_bb = bit(mkPosition(7,0)); 987 | g.kings_bb = bit(mkPosition(4,0)); 988 | g.castle_flags = CASTLE_WHITE_KINGSIDE; 989 | move m; m.from = mkPosition(7,0); m.to = mkPosition(6,0); 990 | gamestate g2 = apply_move(g, m); 991 | assert_equal_u64("test_castling_10_flag_kingrook_delete", 0, g2.castle_flags); 992 | } 993 | // Moving queenside rook deletes flag 994 | { 995 | gamestate g = zerostate(); 996 | g.rooks_bb = bit(mkPosition(0,0)); 997 | g.kings_bb = bit(mkPosition(4,0)); 998 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 999 | move m; m.from = mkPosition(0,0); m.to = mkPosition(2,0); 1000 | gamestate g2 = apply_move(g, m); 1001 | assert_equal_u64("test_castling_11_flag_queenrook_delete", 0, g2.castle_flags); 1002 | } 1003 | // Moving king deletes both flags 1004 | { 1005 | gamestate g = zerostate(); 1006 | g.kings_bb = bit(mkPosition(4,0)); 1007 | g.rooks_bb = 1008 | bit(mkPosition(7,0)) | 1009 | bit(mkPosition(0,0)); 1010 | g.castle_flags = CASTLE_WHITE_KINGSIDE | CASTLE_WHITE_QUEENSIDE; 1011 | move m; m.from = mkPosition(4,0); m.to = mkPosition(5,0); 1012 | gamestate g2 = apply_move(g, m); 1013 | assert_equal_u64("test_castling_12_flag_king_delete", 0, g2.castle_flags); 1014 | } 1015 | // Can't castle with unit blocking rook queenside 1016 | { 1017 | gamestate g = zerostate(); 1018 | g.kings_bb = bit(mkPosition(4,0)); 1019 | g.rooks_bb = bit(mkPosition(0,0)); 1020 | g.castle_flags = CASTLE_WHITE_QUEENSIDE; 1021 | g.knights_bb = bit(mkPosition(1,0)); 1022 | g.current_piece_bb = all_pieces(g); 1023 | 1024 | uint64_t expected = 1025 | bit(mkPosition(3,0)) | 1026 | bit(mkPosition(3,1)) | 1027 | bit(mkPosition(4,1)) | 1028 | bit(mkPosition(5,1)) | 1029 | bit(mkPosition(5,0)); 1030 | uint64_t actual = piece_legal_movepoints(g, mkPosition(4,0)); 1031 | assert_equal_bb("test_castling_13_knight_blocks_rook_queenside", expected, actual); 1032 | } 1033 | // Eating a rook cancels its flag 1034 | { 1035 | gamestate g = zerostate(); 1036 | g.rooks_bb = 1037 | bit(mkPosition(7,0)) | 1038 | bit(mkPosition(0,0)); 1039 | g.current_piece_bb = g.rooks_bb; 1040 | g.rooks_bb |= 1041 | bit(mkPosition(7,7)) | 1042 | bit(mkPosition(0,7)); 1043 | g.castle_flags = 1044 | CASTLE_BLACK_QUEENSIDE | 1045 | CASTLE_BLACK_KINGSIDE; 1046 | // West Rook 1047 | { 1048 | move m; m.from = mkPosition(7,0); m.to = mkPosition(7,7); 1049 | gamestate g2 = swap_board(apply_move(g, m)); 1050 | assert_equal_u64("test_castling_13_remove_flag_on_eat_rook_1", CASTLE_BLACK_QUEENSIDE, g2.castle_flags); 1051 | } 1052 | // East Rook 1053 | { 1054 | move m; m.from = mkPosition(0,0); m.to = mkPosition(0,7); 1055 | gamestate g2 = swap_board(apply_move(g, m)); 1056 | assert_equal_u64("test_castling_13_remove_flag_on_eat_rook_2", CASTLE_BLACK_KINGSIDE, g2.castle_flags); 1057 | } 1058 | } 1059 | } 1060 | 1061 | void test_promotions() 1062 | { 1063 | gamestate g = zerostate(); 1064 | g.pawns_bb = bit(mkPosition(0,6)); 1065 | g.current_player_bb = all_pieces(g); 1066 | // Promotion to Rook 1067 | { 1068 | move m = mkPromotion(mkPosition(0,6), PIECE_ROOK); 1069 | gamestate g2 = swap_board(apply_move(g, m)); 1070 | assert_equal_bb("test_promotions_1_pawns", 0, g2.pawns_bb); 1071 | assert_equal_bb("test_promotions_1_rooks", bit(mkPosition(0,7)), g2.rooks_bb); 1072 | } 1073 | // Promotion to Knight 1074 | { 1075 | move m = mkPromotion(mkPosition(0,6), PIECE_KNIGHT); 1076 | gamestate g2 = swap_board(apply_move(g, m)); 1077 | assert_equal_bb("test_promotions_2_pawns", 0, g2.pawns_bb); 1078 | assert_equal_bb("test_promotions_2_knights", bit(mkPosition(0,7)), g2.knights_bb); 1079 | 1080 | } 1081 | // Promotion to Bishop 1082 | { 1083 | move m = mkPromotion(mkPosition(0,6), PIECE_BISHOP); 1084 | gamestate g2 = swap_board(apply_move(g, m)); 1085 | assert_equal_bb("test_promotions_3_pawns", 0, g2.pawns_bb); 1086 | assert_equal_bb("test_promotions_3_bishops", bit(mkPosition(0,7)), g2.bishops_bb); 1087 | 1088 | } 1089 | // Promotion to Queen 1090 | { 1091 | move m = mkPromotion(mkPosition(0,6), PIECE_QUEEN); 1092 | gamestate g2 = swap_board(apply_move(g, m)); 1093 | assert_equal_bb("test_promotions_4_pawns", 0, g2.pawns_bb); 1094 | assert_equal_bb("test_promotions_4_queens", bit(mkPosition(0,7)), g2.queens_bb); 1095 | } 1096 | // Iterator generates promotions 1097 | { 1098 | assert_equal_int("test_promotions_5_num_moves", 4, num_legal_moves(g)); 1099 | iterator i = mkLegalIterator(g); 1100 | move m1 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1101 | move m2 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1102 | move m3 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1103 | move m4 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1104 | assert_equal_int("test_promotions_5_m1_pc", PIECE_QUEEN, promotion_piece(m1)); 1105 | assert_equal_int("test_promotions_5_m2_pc", PIECE_BISHOP, promotion_piece(m2)); 1106 | assert_equal_int("test_promotions_5_m3_pc", PIECE_KNIGHT, promotion_piece(m3)); 1107 | assert_equal_int("test_promotions_5_m4_pc", PIECE_ROOK, promotion_piece(m4)); 1108 | } 1109 | // Iterator generates promotions 2 1110 | { 1111 | gamestate g = zerostate(); 1112 | g.pawns_bb = bit(mkPosition(1,6)); 1113 | g.current_player_bb = all_pieces(g); 1114 | g.bishops_bb = 1115 | bit(mkPosition(0,7)) | 1116 | bit(mkPosition(2,7)); 1117 | 1118 | iterator i = mkLegalIterator(g); 1119 | move m1 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1120 | move m2 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1121 | move m3 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1122 | move m4 = dereference_iterator(i); i = advance_iterator_legal(g,i); 1123 | assert_equal_int("test_promotions_6_num_moves", 12, num_legal_moves(g)); 1124 | } 1125 | } 1126 | 1127 | uint64_t perft_from(gamestate g, int depth) 1128 | { 1129 | n = 0; 1130 | walk_game_tree(g, depth, tick_counter); 1131 | return n; 1132 | } 1133 | 1134 | /* uint64_t perft(int depth) */ 1135 | /* { */ 1136 | /* return perft_from(new_game(), depth); */ 1137 | /* } */ 1138 | 1139 | int perft_divide_depth; 1140 | 1141 | 1142 | void perft_divide_helper1(gamestate g, move m, int d) 1143 | { 1144 | n = 0; 1145 | 1146 | gamestate g2 = swap_board(apply_move(g, m)); 1147 | walk_game_tree(g2, perft_divide_depth, tick_counter); 1148 | char b[7]; 1149 | print_move(m, b); 1150 | printf("%s\n", b); 1151 | printf(" %lu\n", n); 1152 | } 1153 | 1154 | int perft_divide(gamestate g, int depth) 1155 | { 1156 | perft_divide_depth = depth; 1157 | walk_game_tree(g, 1, perft_divide_helper1); 1158 | } 1159 | 1160 | void test_perft() 1161 | { 1162 | // Initial position 1163 | { 1164 | gamestate g = new_game(); 1165 | /* printf("perft(1): %lu\n", perft(g,1)); */ 1166 | /* printf("perft(2): %lu\n", perft(g,2)); */ 1167 | /* printf("perft(3): %lu\n", perft(g,3)); */ 1168 | /* printf("perft(4): %lu\n", perft(g,4)); */ 1169 | /* printf("perft(5): %lu\n", perft(g,5)); */ 1170 | /* assert_equal_u64("Perft(2)", 400, perft(g,2)); */ 1171 | /* assert_equal_u64("Perft(3)", 8902, perft(g,3)); */ 1172 | /* assert_equal_u64("Perft(4)", 197281, perft(g,4)); */ 1173 | /* assert_equal_u64("Perft(5)", 4865609, perft(g,5)); */ 1174 | } 1175 | // Initial position(read from string) 1176 | { 1177 | gamestate g = parse_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); 1178 | assert_equal_u64("Perft(1)", 20, perft_from(g,1)); 1179 | assert_equal_u64("Perft(2)", 400, perft_from(g,2)); 1180 | assert_equal_u64("Perft(3)", 8902, perft_from(g,3)); 1181 | assert_equal_u64("Perft(4)", 197281, perft_from(g,4)); 1182 | /* assert_equal_u64("Perft(5)", 4865609, perft_from(g,5)); */ 1183 | /* assert_equal_u64("Perft(6)", 119060324, perft_from(g,6)); */ 1184 | /* assert_equal_u64("Perft(7)", 3195901860, perft_from(g,7)); */ 1185 | 1186 | } 1187 | // Castling position 1188 | { 1189 | gamestate g = parse_fen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"); 1190 | // 1: e5f7 - (88799, 88825) 1191 | /* move m; m.from = mkPosition(4,4); m.to = mkPosition(5,6); */ 1192 | /* g = swap_board(apply_move(g, m)); */ 1193 | /* // 2: a1b1 - (2126,2127) */ 1194 | /* move m2; m2.from = mkPosition(0,0); m2.to = mkPosition(1,0); */ 1195 | /* g = swap_board(apply_move(g, m2)); */ 1196 | /* // 3: f7h8 - (40, 41) */ 1197 | /* move m3; m3.from = mkPosition(5,6); m3.to = mkPosition(7,7); */ 1198 | /* g = swap_board(apply_move(g, m3)); */ 1199 | /* perft_divide(g, 1); */ 1200 | /* /\* print_gamestate(g); *\/ */ 1201 | /* print_fen(g); */ 1202 | assert_equal_u64("castling_perft_1", 48, perft_from(g,1)); 1203 | assert_equal_u64("castling_perft_2", 2039, perft_from(g,2)); 1204 | assert_equal_u64("castling_perft_3", 97862, perft_from(g,3)); 1205 | assert_equal_u64("castling_perft_4", 4085603, perft_from(g,4)); 1206 | /* assert_equal_u64("castling_perft_5", 193690690, perft_from(g,5)); */ 1207 | /* assert_equal_u64("good_perft_6", 8031647685, perft_from(g,6)); */ 1208 | } 1209 | // Promotion position 1210 | { 1211 | gamestate g = parse_fen("n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1"); 1212 | assert_equal_u64("promotion_perft_1", 24, perft_from(g,1)); 1213 | assert_equal_u64("promotion_perft_2", 496, perft_from(g,2)); 1214 | assert_equal_u64("promotion_perft_3", 9483, perft_from(g,3)); 1215 | assert_equal_u64("promotion_perft_4", 182838, perft_from(g,4)); 1216 | assert_equal_u64("promotion_perft_5", 3605103, perft_from(g,5)); 1217 | assert_equal_u64("promotion_perft_6", 71179139, perft_from(g,6)); 1218 | } 1219 | } 1220 | 1221 | void test_parsers() 1222 | { 1223 | // Position 1224 | { 1225 | int idx = mkPosition(3,6); 1226 | char buffer[3]; 1227 | print_pos(idx, buffer); 1228 | assert_equal_string("print_pos", "d7", buffer); 1229 | int parsed = parse_pos(buffer); 1230 | assert_equal_int("parse_pos", idx, parsed); 1231 | } 1232 | // Move 1233 | { 1234 | move m = mkPromotion(mkPosition(3,6), PIECE_ROOK); 1235 | char buffer[7]; 1236 | print_move(m, buffer); 1237 | assert_equal_string("print_move", "d7d8/R", buffer); 1238 | move parsed = parse_move(buffer); 1239 | assert_equal_int("parse_move_from", m.from, parsed.from); 1240 | assert_equal_int("parse_move_to", m.to, parsed.to); 1241 | } 1242 | // Gamestate 1243 | { 1244 | const char *reference = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"; 1245 | gamestate g = parse_fen(reference); 1246 | char buffer[100]; 1247 | print_fen(g, buffer); 1248 | assert_equal_string("print_fen", reference, buffer); 1249 | gamestate g2 = parse_fen(buffer); 1250 | assert_equal_u64("parse_fen_rooks", g.rooks_bb, g2.rooks_bb); 1251 | assert_equal_u64("parse_fen_knights", g.knights_bb, g2.knights_bb); 1252 | assert_equal_u64("parse_fen_bishops", g.bishops_bb, g2.bishops_bb); 1253 | assert_equal_u64("parse_fen_queens", g.queens_bb, g2.queens_bb); 1254 | assert_equal_u64("parse_fen_kings", g.kings_bb, g2.kings_bb); 1255 | assert_equal_u64("parse_fen_pawns", g.pawns_bb, g2.pawns_bb); 1256 | assert_equal_u64("parse_fen_current_player", g.current_player_bb, g2.current_player_bb); 1257 | assert_equal_int("parse_fen_en_passant", g.en_passant_sq, g2.en_passant_sq); 1258 | assert_equal_u64("parse_fen_castle", g.castle_flags, g2.castle_flags); 1259 | } 1260 | // Gamestate (castle flags 1) 1261 | { 1262 | const char *fen = "rnb1kb1r/ppp1p2p/6p1/6pn/P1BqN3/R7/1PP2PPP/4K1NR b Kkq - 0 1"; 1263 | gamestate g = parse_fen(fen); 1264 | char actual[200]; 1265 | g = apply_move(g, swap_move(parse_move("d4e4"))); 1266 | print_fen(g, actual); 1267 | const char *expected = "rnb1kb1r/ppp1p2p/6p1/6pn/P1B1q3/R7/1PP2PPP/4K1NR w Kkq - 0 1"; 1268 | assert_equal_string("test_parser_castle_flags", expected, actual); 1269 | } 1270 | // Gamestate (castle flags 2) 1271 | { 1272 | const char *fen = "2b1kb1r/p1p2p2/5n1p/2qp2p1/3rp3/2P3P1/PPQPBP1P/RNB1K1NR w KQk - 0 1"; 1273 | gamestate g = parse_fen(fen); 1274 | char actual[200]; 1275 | g = apply_move(g, parse_move("e1f1")); 1276 | print_fen(g, actual); 1277 | const char *expected = "2b1kb1r/p1p2p2/5n1p/2qp2p1/3rp3/2P3P1/PPQPBP1P/RNB2KNR b k - 0 1"; 1278 | assert_equal_string("test_parser_castle_flags_2", expected, actual); 1279 | } 1280 | } 1281 | 1282 | int negamax_simple(gamestate g, int depth, int color) { 1283 | if (depth == 0) 1284 | return color*evaluate(g); 1285 | int max = VALUE_NEGAMAX_START; 1286 | for (iterator i = mkLegalIterator(g); ! is_iterator_finished(i); i = advance_iterator_legal(g, i)) { 1287 | move m = dereference_iterator(i); 1288 | gamestate g2 = apply_move(g, m); 1289 | int score = -negamax_simple(g2, depth - 1, color*-1); 1290 | if (score > max) 1291 | max = score; 1292 | } 1293 | return max; 1294 | } 1295 | 1296 | void test_search() 1297 | { 1298 | { 1299 | /* gamestate g = new_game(); */ 1300 | /* /\* move m = best_move(g); *\/ */ 1301 | /* print_move(m); */ 1302 | /* int score = negamax_original(g); */ 1303 | /* printf("Score: %d\n", score); */ 1304 | /* negamax_ret x = negamax(g); */ 1305 | /* print_move(x.m); */ 1306 | /* printf("\nScore: %d\n", x.score); */ 1307 | } 1308 | } 1309 | 1310 | /* int main() */ 1311 | /* { */ 1312 | /* gamestate g = new_game(); */ 1313 | /* move m = parse_move("e2e4"); */ 1314 | /* g = apply_move(g, m); */ 1315 | 1316 | /* printf("%lu", result); */ 1317 | /* return 0; */ 1318 | /* } */ 1319 | 1320 | void print_move_out(move m) 1321 | { 1322 | char c[10]; 1323 | print_move(m, c); 1324 | printf("%s|", c); 1325 | } 1326 | 1327 | void print_fen_out(gamestate g) 1328 | { 1329 | char c[300]; 1330 | print_fen(g, c); 1331 | printf("%s\n", c); 1332 | } 1333 | 1334 | gamestate computer_move(gamestate g) 1335 | { 1336 | move m = best_move(g,3); 1337 | g = apply_move(g, m); 1338 | print_move_out(m); 1339 | print_fen_out(g); 1340 | return g; 1341 | } 1342 | 1343 | gamestate player_move(gamestate g, const char *m_str) 1344 | { 1345 | move m = parse_move(m_str); 1346 | print_move_out(m); 1347 | if (! g.is_white) 1348 | m = swap_move(m); 1349 | g = apply_move(g, m); 1350 | print_fen_out(g); 1351 | return g; 1352 | } 1353 | 1354 | int main() { 1355 | 1356 | 1357 | /* test_ray(); */ 1358 | /* test_rook(); */ 1359 | /* test_pawn(); */ 1360 | /* test_knight(); */ 1361 | /* test_king(); */ 1362 | /* test_bishop(); */ 1363 | /* test_iterator(); */ 1364 | /* test_apply_move(); */ 1365 | /* test_check(); */ 1366 | /* test_castling(); */ 1367 | /* test_promotions(); */ 1368 | /* test_perft(); */ 1369 | test_parsers(); 1370 | // test_search(); 1371 | 1372 | gamestate g = parse_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); 1373 | g = player_move(g, "e2e3"); // g = computer_move(g); 1374 | g = player_move(g, "d7d6"); 1375 | g = player_move(g, "d1h5"); // g = computer_move(g); 1376 | g = player_move(g, "g8f6"); 1377 | g = player_move(g, "h5g5"); // g = computer_move(g); 1378 | g = player_move(g, "h7h6"); 1379 | g = player_move(g, "g5f4"); // g = computer_move(g); 1380 | g = player_move(g, "g7g5"); 1381 | g = player_move(g, "f4d4"); // g = computer_move(g); 1382 | g = player_move(g, "e7e5"); 1383 | g = player_move(g, "d4a4"); // g = computer_move(g); 1384 | g = player_move(g, "c8d7"); 1385 | g = player_move(g, "a4c4"); // g = computer_move(g); 1386 | g = player_move(g, "d6d5"); 1387 | g = player_move(g, "c4b3"); // g = computer_move(g); 1388 | g = player_move(g, "b8c6"); 1389 | g = player_move(g, "g1f3"); // g = computer_move(g); 1390 | g = player_move(g, "e5e4"); 1391 | g = player_move(g, "f3g1"); // g = computer_move(g); 1392 | g = player_move(g, "c6b4"); 1393 | g = player_move(g, "g2g3"); // g = computer_move(g); 1394 | g = player_move(g, "d8e7"); 1395 | g = player_move(g, "f1e2"); // g = computer_move(g); 1396 | g = player_move(g, "e7c5"); 1397 | g = player_move(g, "c2c3"); // g = computer_move(g); 1398 | g = player_move(g, "b4c6"); 1399 | g = player_move(g, "b3b7"); // g = computer_move(g); 1400 | g = player_move(g, "a8b8"); 1401 | g = player_move(g, "b7a6"); // g = computer_move(g); 1402 | g = player_move(g, "d7c8"); 1403 | g = player_move(g, "a6a4"); // g = computer_move(g); 1404 | g = player_move(g, "b8b4"); 1405 | g = player_move(g, "a4c2"); // g = computer_move(g); 1406 | g = player_move(g, "c6d4"); 1407 | g = player_move(g, "e3d4"); // g = computer_move(g); 1408 | g = player_move(g, "b4d4"); 1409 | g = player_move(g, "e1f1"); // g = computer_move(g); 1410 | g = player_move(g, "c8g4"); 1411 | g = player_move(g, "e2a6"); // g = computer_move(g); 1412 | g = player_move(g, "c5c6"); 1413 | g = player_move(g, "f1e1"); // g = computer_move(g); 1414 | g = player_move(g, "d4a4"); 1415 | g = player_move(g, "a6f1"); // g = computer_move(g); 1416 | g = player_move(g, "d5d4"); 1417 | g = player_move(g, "c2b3"); // g = computer_move(g); 1418 | g = player_move(g, "f8b4"); 1419 | g = player_move(g, "h2h4"); // g = computer_move(g); 1420 | g = player_move(g, "e4e3"); 1421 | g = player_move(g, "f2f3"); // g = computer_move(g); 1422 | g = player_move(g, "e3d2"); 1423 | g = player_move(g, "e1d2"); // g = computer_move(g); 1424 | g = player_move(g, "d4c3"); 1425 | g = player_move(g, "d2c2"); // g = computer_move(g); 1426 | g = player_move(g, "g4f5"); 1427 | g = player_move(g, "f1d3"); // g = computer_move(g); 1428 | g = player_move(g, "f5d3"); 1429 | g = player_move(g, "c2d3"); // g = computer_move(g); 1430 | g = player_move(g, "c6d5"); 1431 | g = player_move(g, "b3d5"); // g = computer_move(g); 1432 | g = player_move(g, "f6d5"); 1433 | g = player_move(g, "h1h2"); // g = computer_move(g); 1434 | g = player_move(g, "e8g8"); 1435 | g = player_move(g, "g1h3"); // g = computer_move(g); 1436 | g = player_move(g, "f8e8"); 1437 | g = player_move(g, "f3f4"); // g = computer_move(g); 1438 | g = player_move(g, "e8e3"); 1439 | g = player_move(g, "d3c4"); // g = computer_move(g); 1440 | g = player_move(g, "c3b2"); 1441 | g = player_move(g, "c1b2"); // g = computer_move(g); 1442 | g = player_move(g, "b4c3"); 1443 | g = player_move(g, "c4c5"); // g = computer_move(g); 1444 | g = player_move(g, "a4a5"); 1445 | g = player_move(g, "c5c6"); // g = computer_move(g); 1446 | g = player_move(g, "e3e6"); 1447 | g = player_move(g, "c6b7"); // g = computer_move(g); 1448 | g = player_move(g, "a5b5"); 1449 | g = player_move(g, "b7c8"); // g = computer_move(g); 1450 | g = player_move(g, "b5b2"); 1451 | g = player_move(g, "h2h1"); // g = computer_move(g); 1452 | g = player_move(g, "c3a5"); 1453 | g = player_move(g, "f4f5"); // g = computer_move(g); 1454 | g = player_move(g, "e6d6"); 1455 | g = player_move(g, "b1a3"); // g = computer_move(g); 1456 | g = player_move(g, "d5e7"); 1457 | /* gamestate g = parse_fen("rnb1kb1r/ppp1p2p/6p1/6pn/P1BqN3/8/1PP2PPP/R3K1NR w KQkq - 0 1"); */ 1458 | /* g = apply_move(g, parse_move("a1a3")); */ 1459 | /* char fen[300]; */ 1460 | /* print_fen(g, fen); */ 1461 | /* printf("%s\n", fen); */ 1462 | /* gamestate g = new_game(); */ 1463 | /* char fen[300]; */ 1464 | /* g = apply_move(g, parse_move("e2e4")); */ 1465 | /* move m = best_move(g, 3); */ 1466 | 1467 | /* print_fen(g, fen); */ 1468 | /* printf("%s\n", fen); */ 1469 | 1470 | /* g = apply_move(g, swap_move(parse_move("d7d5"))); */ 1471 | /* print_fen(g, fen); */ 1472 | /* printf("%s\n", fen); */ 1473 | 1474 | 1475 | /* gamestate g = new_game(); */ 1476 | /* iterator i = mkIterator(g); */ 1477 | 1478 | /* print_bitboard(i.current_piece_bb); */ 1479 | 1480 | /* gamestate g = new_game(); */ 1481 | /* // 1: c2c4 */ 1482 | /* move m1; m1.from = mkPosition(2,1); m1.to = mkPosition(2,3); */ 1483 | /* g = swap_board(apply_move(g, m1)); */ 1484 | /* // 2: d2d4 */ 1485 | /* move m2; m2.from = mkPosition(3,1); m2.to = mkPosition(3,3); */ 1486 | /* g = swap_board(apply_move(g, m2)); */ 1487 | /* // 3: c4d5 */ 1488 | /* move m3; m3.from = mkPosition(2,3); m3.to = mkPosition(3,4); */ 1489 | /* g = swap_board(apply_move(g, m3)); */ 1490 | /* // 4: c1a3 */ 1491 | /* move m4; m4.from = mkPosition(2,0); m4.to = mkPosition(0,2); */ 1492 | /* g = swap_board(apply_move(g, m4)); */ 1493 | /* // 5: a2a3 */ 1494 | /* move m5; m5.from = mkPosition(0,1); m5.to = mkPosition(0,2); */ 1495 | /* g = swap_board(apply_move(g, m4)); */ 1496 | 1497 | // NOTE: D1C1 as m6 is in roce, but not the redshift shellcode. 1498 | 1499 | /* g = swap_board(apply_move(g, m2)); */ 1500 | /* move m3; m3.from = mkPosition(0,3); m3.to = mkPosition(0,4); */ 1501 | /* g = swap_board(apply_move(g, m3)); */ 1502 | /* g = apply_move(g, m3); */ 1503 | /* perft_divide(g,3); */ 1504 | /* print_fen(g); */ 1505 | /* // 1: B1A3 */ 1506 | 1507 | /* g = swap_board(apply_move(g, m1)); */ 1508 | /* /\* // 2: B1A3 *\/ */ 1509 | /* g = swap_board(apply_move(g, m1)); */ 1510 | /* print_fen(g); */ 1511 | /* /\* print_gamestate(g); *\/ */ 1512 | // perft_divide(g, 1); 1513 | /* print_gamestate(g); */ 1514 | /* printf("== rooks\n"); print_bitboard(g.rooks_bb); */ 1515 | /* printf("== pawns\n"); print_bitboard(g.pawns_bb); */ 1516 | 1517 | /* print_moves(g); */ 1518 | 1519 | } 1520 | /* int main() */ 1521 | /* { */ 1522 | /* test_parsers(); */ 1523 | /* /\* packed_move m; *\/ */ 1524 | /* /\* m.packed = 68719476737; // b1a3 *\/ */ 1525 | /* /\* print_move(m.m); *\/ */ 1526 | /* /\* gamestate g = new_game(); *\/ */ 1527 | /* /\* printf("rooks: %ld\n", g.rooks_bb); *\/ */ 1528 | /* /\* printf("knights: %ld\n", g.knights_bb); *\/ */ 1529 | /* /\* printf("bishops: %ld\n", g.bishops_bb); *\/ */ 1530 | /* /\* printf("queens: %ld\n", g.queens_bb); *\/ */ 1531 | /* /\* printf("kings: %ld\n", g.kings_bb); *\/ */ 1532 | /* /\* printf("pawns: %ld\n", g.pawns_bb); *\/ */ 1533 | /* /\* printf("player: %ld\n", g.current_player_bb); *\/ */ 1534 | /* /\* printf("en_passant_sq: %d\n", g.en_passant_sq); *\/ */ 1535 | /* /\* printf("castle_flags: %ld\n", g.castle_flags); *\/ */ 1536 | /* /\* printf("perft: %lu\n", custom_main(g)); *\/ */ 1537 | /* } */ 1538 | --------------------------------------------------------------------------------