mirror of https://github.com/Cisco-Talos/clamav
parent
b4ff5537e8
commit
81030038e5
@ -0,0 +1,530 @@ |
||||
/*
|
||||
* Copyright (C) 2006 aCaB <acab@clamav.net> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
/*
|
||||
** unsp.c |
||||
** |
||||
** 11/10/2k6 - Merge started. |
||||
** |
||||
*/ |
||||
|
||||
/*
|
||||
** Plays around with NsPack compressed executables |
||||
** |
||||
** This piece of code is dedicated to Damian Put |
||||
** who I made a successful and wealthy man. |
||||
** |
||||
** Damian, you owe me a pint! |
||||
*/ |
||||
|
||||
/*
|
||||
** TODO: |
||||
** |
||||
** - Investigate the "unused" code in NsPack |
||||
** - Fetch all the nspacked samples from the zoo and run extensive testing |
||||
** - Add bound checks |
||||
** - Test against the zoo again |
||||
** - Perform regression testing against the full zoo
|
||||
** - check nested |
||||
** - look at the 64bit version (one of these days) |
||||
** |
||||
*/ |
||||
|
||||
/*
|
||||
|
||||
FIXME: clean this rubbish |
||||
|
||||
|
||||
init_and_check_dll_loadflags(); |
||||
|
||||
nsp1:004359FE add edi, [ebp-28Dh] |
||||
nsp1:00435A04 mov ebx, edi |
||||
nsp1:00435A06 cmp dword ptr [edi], 0 |
||||
nsp1:00435A09 jnz short loc_435A15 |
||||
nsp1:00435A0B add edi, 4 |
||||
nsp1:00435A0E mov ecx, 0 |
||||
nsp1:00435A13 jmp short loc_435A2B |
||||
nsp1:00435A15 ; --------------------------------------------------------------------------- |
||||
nsp1:00435A15 |
||||
nsp1:00435A15 loc_435A15: ; CODE XREF: start+349EEj |
||||
nsp1:00435A15 mov ecx, 1 |
||||
nsp1:00435A1A add edi, [ebx] |
||||
nsp1:00435A1C add ebx, 4 |
||||
nsp1:00435A1F |
||||
nsp1:00435A1F loc_435A1F: ; CODE XREF: start+34A3Dj |
||||
nsp1:00435A1F cmp dword ptr [ebx], 0 |
||||
nsp1:00435A22 jz short loc_435A5A |
||||
nsp1:00435A24 add [ebx], edx |
||||
nsp1:00435A26 mov esi, [ebx] |
||||
nsp1:00435A28 add edi, [ebx+4] |
||||
nsp1:00435A2B |
||||
nsp1:00435A2B loc_435A2B: ; CODE XREF: start+349F8j |
||||
nsp1:00435A2B push edi |
||||
nsp1:00435A2C push ecx |
||||
nsp1:00435A2D push edx |
||||
nsp1:00435A2E push ebx |
||||
nsp1:00435A2F push dword ptr [ebp-1D1h] ; VirtualFree |
||||
nsp1:00435A35 push dword ptr [ebp-1D5h] ; alloc |
||||
nsp1:00435A3B mov edx, esi |
||||
nsp1:00435A3D mov ecx, edi |
||||
nsp1:00435A3F mov eax, offset get_byte |
||||
nsp1:00435A44 int 3 ; Trap to Debugger |
||||
nsp1:00435A45 add eax, 5A9h |
||||
nsp1:00435A4A call eax ; real_unpack ; edx=401000 |
||||
nsp1:00435A4A ; ecx=436282 |
||||
nsp1:00435A4C pop ebx |
||||
nsp1:00435A4D pop edx |
||||
nsp1:00435A4E pop ecx |
||||
nsp1:00435A4F pop edi |
||||
nsp1:00435A50 cmp ecx, 0 |
||||
nsp1:00435A53 jz short loc_435A5A |
||||
nsp1:00435A55 add ebx, 8 |
||||
nsp1:00435A58 jmp short loc_435A1F |
||||
nsp1:00435A5A ; --------------------------------------------------------------------------- |
||||
nsp1:00435A5A |
||||
nsp1:00435A5A loc_435A5A: ; CODE XREF: start+34A07j |
||||
nsp1:00435A5A ; start+34A38j |
||||
nsp1:00435A5A push 8000h |
||||
|
||||
*/ |
||||
|
||||
#if HAVE_CONFIG_H |
||||
#include "clamav-config.h" |
||||
#endif |
||||
|
||||
#ifdef CL_EXPERIMENTAL |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#include "cltypes.h" |
||||
#include "clamav.h" |
||||
#include "others.h" |
||||
#include "rebuildpe.h" |
||||
#include "unsp.h" |
||||
|
||||
|
||||
/* real_unpack(start_of_stuff, dest, malloc, free); */ |
||||
uint32_t unspack(char *start_of_stuff, char *dest, cli_ctx *ctx, uint32_t rva, uint32_t base, uint32_t ep, int file) { |
||||
uint8_t c = *start_of_stuff; |
||||
uint32_t i,firstbyte,tre,allocsz,tablesz,dsize,ssize; |
||||
uint16_t *table; |
||||
char *dst = dest; |
||||
char *src = start_of_stuff+0xd; |
||||
struct SECTION section; |
||||
|
||||
if (c>=0xe1) return 1; |
||||
|
||||
if (c>=0x2d) { |
||||
firstbyte = i = c/0x2d; |
||||
do {c+=0xd3;} while (--i); |
||||
} else firstbyte = 0; |
||||
|
||||
if (c>=9) { |
||||
allocsz = i = c/9; |
||||
do {c+=0xf7;} while (--i); |
||||
} else allocsz = 0; |
||||
|
||||
tre = c; |
||||
i = allocsz; |
||||
c = (tre+i)&0xff; |
||||
tablesz = ((0x300<<c)+0x736)*sizeof(uint16_t); |
||||
if(ctx->limits && ctx->limits->maxfilesize && tablesz > ctx->limits->maxfilesize) { |
||||
return 1; /* Should be ~15KB, if it's so big it's prolly just not nspacked */ |
||||
} |
||||
|
||||
cli_dbgmsg("unsp: table size = %d\n", tablesz); |
||||
if (!(table = cli_malloc(tablesz))) return 1; |
||||
|
||||
dsize = cli_readint32(start_of_stuff+9); |
||||
ssize = cli_readint32(start_of_stuff+5); |
||||
|
||||
tre = very_real_unpack(table,tablesz,tre,allocsz,firstbyte,src,ssize,dst,dsize); |
||||
free(table); |
||||
if (tre) return 1; |
||||
|
||||
section.raw=0; |
||||
section.rsz = dsize; |
||||
section.vsz = dsize; |
||||
section.rva = rva; |
||||
if ( (src = rebuildpe(dest, §ion, 1, base, ep, 0, 0)) ) { |
||||
if (cli_writen(file, src, 0x148+0x80+0x28+dsize)!=-1) { |
||||
free(src); |
||||
return 0; |
||||
} |
||||
free(src); |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
uint32_t very_real_unpack(uint16_t *table, uint32_t tablesz, uint32_t tre, uint32_t allocsz, uint32_t firstbyte, char *src, uint32_t ssize, char *dst, uint32_t dsize) { |
||||
struct UNSP read_struct; |
||||
uint32_t i = (0x300<<((allocsz+tre)&0xff)) + 0x736; |
||||
|
||||
uint32_t previous_bit = 0; |
||||
uint32_t unpacked_so_far = 0; |
||||
uint32_t backbytes = 1; |
||||
uint32_t oldbackbytes = 1; |
||||
uint32_t old_oldbackbytes = 1; |
||||
uint32_t old_old_oldbackbytes = 1; |
||||
|
||||
uint32_t damian = 0; |
||||
uint32_t put = (1<<(allocsz&0xff))-1; |
||||
|
||||
uint32_t bielle = 0; |
||||
|
||||
firstbyte = (1<<(firstbyte&0xff))-1; |
||||
|
||||
if (tablesz < i*sizeof(uint16_t)) return 2; |
||||
|
||||
/* init table */ |
||||
while (i) table[--i]=0x400; |
||||
|
||||
/* table noinit */ |
||||
|
||||
/* get_five - inlined */ |
||||
read_struct.error = 0; |
||||
read_struct.oldval = 0; |
||||
read_struct.src_curr = src; |
||||
read_struct.bitmap = 0xffffffff; |
||||
read_struct.src_end = src + ssize; |
||||
read_struct.table = (char *)table; |
||||
read_struct.tablesz = tablesz; |
||||
|
||||
for ( i = 0; i<5 ; i++) read_struct.oldval = (read_struct.oldval<<8) | get_byte(&read_struct); |
||||
if (read_struct.error) return 1; |
||||
/* if (!dsize) return 0; - checked in pe.c */ |
||||
|
||||
|
||||
/* very_unpacking_loop */ |
||||
|
||||
while (1) { |
||||
uint32_t backsize = firstbyte&unpacked_so_far; |
||||
uint32_t tpos; |
||||
uint32_t temp = damian; |
||||
|
||||
if (read_struct.error) return 1; /* checked once per mainloop, keeps the code readable and it's still safe */ |
||||
|
||||
if (!getbit_from_table(&table[(damian<<4) + backsize], &read_struct)) { /* no_mainbit */ |
||||
|
||||
uint32_t shft = 8 - (tre&0xff); |
||||
shft &= 0xff; |
||||
tpos = (bielle>>shft) + ((put&unpacked_so_far)<<(tre&0xff)); |
||||
tpos *=3; |
||||
tpos<<=8; |
||||
|
||||
if ((int32_t)damian>=4) { /* signed */ |
||||
if ((int32_t)damian>=0xa) { /* signed */ |
||||
damian -= 6; |
||||
} else { |
||||
damian -= 3; |
||||
} |
||||
} else { |
||||
damian=0; |
||||
} |
||||
|
||||
/* 44847E */ |
||||
if (previous_bit) { |
||||
if (!CLI_ISCONTAINED(dst, dsize, &dst[unpacked_so_far - backbytes], 1)) return 1; |
||||
ssize = (ssize&0xffffff00) | (uint8_t)dst[unpacked_so_far - backbytes]; /* FIXME! ssize is not static */ |
||||
bielle = get_100_bits_from_tablesize(&table[tpos+0x736], &read_struct, ssize); |
||||
previous_bit=0; |
||||
} else { |
||||
bielle = get_100_bits_from_table(&table[tpos+0x736], &read_struct); |
||||
} |
||||
|
||||
/* unpack_one_byte - duplicated */ |
||||
if (!CLI_ISCONTAINED(dst, dsize, &dst[unpacked_so_far], 1)) return 1; |
||||
dst[unpacked_so_far] = bielle; |
||||
unpacked_so_far++; |
||||
if (unpacked_so_far>=dsize) return 0; |
||||
continue; |
||||
|
||||
} else { /* got_mainbit */ |
||||
|
||||
bielle = previous_bit = 1; |
||||
|
||||
if (getbit_from_table(&table[damian+0xc0], &read_struct)) { |
||||
if (!getbit_from_table(&table[damian+0xcc], &read_struct)) { |
||||
tpos = damian+0xf; |
||||
tpos <<=4; |
||||
tpos += backsize; |
||||
if (!getbit_from_table(&table[tpos], &read_struct)) { |
||||
if (!unpacked_so_far) return bielle; /* FIXME: WTF?! */ |
||||
|
||||
damian = 2*((int32_t)damian>=7)+9; /* signed */ |
||||
if (!CLI_ISCONTAINED(dst, dsize, &dst[unpacked_so_far - backbytes], 1)) return 1; |
||||
bielle = (uint8_t)dst[unpacked_so_far - backbytes]; |
||||
/* unpack_one_byte - real */ |
||||
dst[unpacked_so_far] = bielle; |
||||
unpacked_so_far++; |
||||
if (unpacked_so_far>=dsize) return 0; |
||||
continue; |
||||
|
||||
} else { /* gotbit_tre */ |
||||
backsize = get_n_bits_from_tablesize(&table[0x534], &read_struct, backsize); |
||||
damian = ((int32_t)damian>=7); /* signed */ |
||||
damian = ((damian-1) & 0xfffffffd)+0xb; |
||||
/* jmp checkloop_and_backcopy (uses edx) */ |
||||
} /* gotbit_uno ends */ |
||||
} else { /* gotbit_due */ |
||||
if (!getbit_from_table(&table[damian+0xd8], &read_struct)) { |
||||
tpos = oldbackbytes; |
||||
} else { |
||||
if (!getbit_from_table(&table[damian+0xe4], &read_struct)) { |
||||
tpos = old_oldbackbytes; |
||||
} else { |
||||
/* set_old_old_oldback */ |
||||
tpos = old_old_oldbackbytes; |
||||
old_old_oldbackbytes = old_oldbackbytes; |
||||
} |
||||
/* set_old_oldback */ |
||||
old_oldbackbytes = oldbackbytes; |
||||
} |
||||
/* set_oldback */ |
||||
oldbackbytes = backbytes; |
||||
backbytes = tpos; |
||||
|
||||
backsize = get_n_bits_from_tablesize(&table[0x534], &read_struct, backsize); |
||||
damian = ((int32_t)damian>=7); /* signed */ |
||||
damian = ((damian-1) & 0xfffffffd)+0xb; |
||||
/* jmp checkloop_and_backcopy (uses edx) */ |
||||
} /* gotbit_due ends */ |
||||
} else { /* gotbit_uno */ |
||||
|
||||
old_old_oldbackbytes = old_oldbackbytes; |
||||
old_oldbackbytes = oldbackbytes; |
||||
oldbackbytes = backbytes; |
||||
|
||||
damian = ((int32_t)damian>=7); /* signed */ |
||||
damian = ((damian-1) & 0xfffffffd)+0xa; |
||||
|
||||
backsize = get_n_bits_from_tablesize(&table[0x332], &read_struct, backsize); |
||||
|
||||
tpos = ((int32_t)backsize>=4)?3:backsize; /* signed */ |
||||
tpos<<=6; |
||||
tpos = get_n_bits_from_table(&table[0x1b0+tpos], 6, &read_struct); |
||||
|
||||
if (tpos>=4) { /* signed */ |
||||
|
||||
uint32_t s = tpos; |
||||
s>>=1; |
||||
s--; |
||||
|
||||
temp = (tpos & bielle) | 2; |
||||
temp<<=(s&0xff); |
||||
|
||||
|
||||
if ((int32_t)tpos<0xe) { |
||||
temp += get_bb(&table[(temp-tpos)+0x2af], s, &read_struct); |
||||
} else { |
||||
s += 0xfffffffc; |
||||
tpos = get_bitmap(&read_struct, s); |
||||
tpos <<=4; |
||||
temp += tpos; |
||||
temp += get_bb(&table[0x322], 4, &read_struct); |
||||
} |
||||
} else { |
||||
/* gotbit_uno_out1 */ |
||||
backbytes = temp = tpos; |
||||
} |
||||
/* gotbit_uno_out2 */ |
||||
backbytes = temp+1; |
||||
/* jmp checkloop_and_backcopy (uses edx) */ |
||||
} /* gotbit_uno ends */ |
||||
|
||||
/* checkloop_and_backcopy */ |
||||
if (!backbytes) return 0; /* very_real_unpack_end */ |
||||
if (backbytes > unpacked_so_far) return bielle; /* FIXME: WTF?! */ |
||||
|
||||
backsize +=2; |
||||
|
||||
if (!CLI_ISCONTAINED(dst, dsize, &dst[unpacked_so_far], backsize) || |
||||
!CLI_ISCONTAINED(dst, dsize, &dst[unpacked_so_far - backbytes], backsize) |
||||
) { |
||||
cli_dbgmsg("%x %x %x %x\n", dst, dsize, &dst[unpacked_so_far], backsize); |
||||
return 1; |
||||
} |
||||
|
||||
do { |
||||
dst[unpacked_so_far] = dst[unpacked_so_far - backbytes]; |
||||
unpacked_so_far++; |
||||
} while (--backsize && unpacked_so_far<dsize); |
||||
bielle = (uint8_t)dst[unpacked_so_far - 1]; |
||||
|
||||
if (unpacked_so_far>=dsize) return 0; |
||||
|
||||
} /* got_mainbit ends */ |
||||
|
||||
} /* while true ends */ |
||||
} |
||||
|
||||
|
||||
|
||||
uint32_t get_byte(struct UNSP *read_struct) { |
||||
|
||||
uint32_t ret; |
||||
|
||||
if (read_struct->src_curr >= read_struct->src_end) { |
||||
read_struct->error = 1; |
||||
return 0xff; |
||||
} |
||||
ret = *(read_struct->src_curr); |
||||
read_struct->src_curr++; |
||||
return ret&0xff; |
||||
} |
||||
|
||||
|
||||
int getbit_from_table(uint16_t *intable, struct UNSP *read_struct) { |
||||
|
||||
uint32_t nval; |
||||
if (!CLI_ISCONTAINED((char *)read_struct->table, read_struct->tablesz, (char *)intable, sizeof(uint16_t))) { |
||||
read_struct->error = 1; |
||||
return 0xff; |
||||
} |
||||
nval = *intable * (read_struct->bitmap>>0xb); |
||||
|
||||
if (read_struct->oldval<nval) { /* unsigned */ |
||||
uint32_t sval; |
||||
read_struct->bitmap = nval; |
||||
nval = *intable; |
||||
sval = 0x800 - nval; |
||||
sval = ((int32_t)sval)>>5; /* signed */ |
||||
sval += nval; |
||||
*intable=sval; |
||||
if (read_struct->bitmap<0x1000000) { /* unsigned */ |
||||
read_struct->oldval = (read_struct->oldval<<8) | get_byte(read_struct); |
||||
read_struct->bitmap<<=8; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
read_struct->bitmap -= nval; |
||||
read_struct->oldval -= nval; |
||||
|
||||
nval = *intable; |
||||
nval -= (nval>>5); /* word, unsigned */ |
||||
*intable=nval; |
||||
|
||||
if (read_struct->bitmap<0x1000000) { /* unsigned */ |
||||
read_struct->oldval = (read_struct->oldval<<8) | get_byte(read_struct); |
||||
read_struct->bitmap<<=8; |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
|
||||
uint32_t get_100_bits_from_tablesize(uint16_t *intable, struct UNSP *read_struct, uint32_t ssize) { |
||||
|
||||
uint32_t count = 1; |
||||
|
||||
while (count<0x100) { |
||||
uint32_t lpos, tpos; |
||||
lpos = ssize&0xff; |
||||
ssize=(ssize&0xffffff00)|((lpos<<1)&0xff); |
||||
lpos>>=7; |
||||
tpos = lpos+1; |
||||
tpos<<=8; |
||||
tpos+=count; |
||||
tpos = getbit_from_table(&intable[tpos], read_struct); |
||||
count=(count*2)|tpos; |
||||
if (lpos!=tpos) { |
||||
/* second loop */ |
||||
while (count<0x100) |
||||
count = (count*2)|getbit_from_table(&intable[count], read_struct); |
||||
} |
||||
}
|
||||
return count&0xff; |
||||
} |
||||
|
||||
|
||||
uint32_t get_100_bits_from_table(uint16_t *intable, struct UNSP *read_struct) { |
||||
uint32_t count = 1; |
||||
|
||||
while (count<0x100) |
||||
count = (count*2)|getbit_from_table(&intable[count], read_struct); |
||||
return count&0xff; |
||||
} |
||||
|
||||
|
||||
uint32_t get_n_bits_from_table(uint16_t *intable, uint32_t bits, struct UNSP *read_struct) { |
||||
uint32_t count = 1; |
||||
uint32_t bitcounter; |
||||
|
||||
/* if (bits) { always set! */ |
||||
bitcounter = bits; |
||||
while (bitcounter--) |
||||
count = count*2 + getbit_from_table(&intable[count], read_struct); |
||||
/* } */ |
||||
|
||||
return count-(1<<(bits&0xff)); |
||||
} |
||||
|
||||
|
||||
uint32_t get_n_bits_from_tablesize(uint16_t *intable, struct UNSP *read_struct, uint32_t backsize) { |
||||
|
||||
if (!getbit_from_table(intable, read_struct)) |
||||
return get_n_bits_from_table(&intable[(backsize<<3)+2], 3, read_struct); |
||||
|
||||
if (!getbit_from_table(&intable[1], read_struct)) |
||||
return 8+get_n_bits_from_table(&intable[(backsize<<3)+0x82], 3, read_struct); |
||||
|
||||
return 0x10+get_n_bits_from_table(&intable[0x102], 8, read_struct); |
||||
} |
||||
|
||||
|
||||
uint32_t get_bb(uint16_t *intable, uint32_t back, struct UNSP *read_struct) { |
||||
uint32_t pos = 1; |
||||
uint32_t bb = 0; |
||||
uint32_t i; |
||||
|
||||
if ((int32_t)back<=0) /* signed */ |
||||
return 0; |
||||
|
||||
for (i=0;i<back;i++) { |
||||
uint32_t bit = getbit_from_table(&intable[pos], read_struct); |
||||
pos=(pos*2) + bit; |
||||
bb|=(bit<<i); |
||||
} |
||||
return bb; |
||||
} |
||||
|
||||
|
||||
uint32_t get_bitmap(struct UNSP *read_struct, uint32_t bits) { |
||||
uint32_t retv = 0; |
||||
|
||||
if ((int32_t)bits<=0) return 0; /* signed */ |
||||
|
||||
while (bits--) { |
||||
read_struct->bitmap>>=1; /* unsigned */ |
||||
retv<<=1; |
||||
if (read_struct->oldval>=read_struct->bitmap) { /* unsigned */ |
||||
read_struct->oldval-=read_struct->bitmap; |
||||
retv|=1; |
||||
} |
||||
if (read_struct->bitmap<0x1000000) { |
||||
read_struct->bitmap<<=8; |
||||
read_struct->oldval = (read_struct->oldval<<8) | get_byte(read_struct); |
||||
} |
||||
} |
||||
return retv; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,50 @@ |
||||
/*
|
||||
* Copyright (C) 2006 aCaB <acab@clamav.net> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#ifdef CL_EXPERIMENTAL |
||||
#ifndef __UNSP_H |
||||
#define __UNSP_H |
||||
|
||||
#include "cltypes.h" |
||||
#include "others.h" |
||||
|
||||
struct UNSP { |
||||
char *src_curr; |
||||
char *src_end; |
||||
uint32_t bitmap; |
||||
uint32_t oldval; |
||||
int error; |
||||
/* the following are not in the original structure */ |
||||
char *table; |
||||
uint32_t tablesz; |
||||
}; |
||||
|
||||
uint32_t unspack(char *, char *, cli_ctx *, uint32_t, uint32_t, uint32_t, int); |
||||
uint32_t very_real_unpack(uint16_t *, uint32_t, uint32_t, uint32_t, uint32_t, char *, uint32_t, char *, uint32_t); |
||||
uint32_t get_byte(struct UNSP *); |
||||
int getbit_from_table(uint16_t *, struct UNSP *); |
||||
uint32_t get_100_bits_from_tablesize(uint16_t *, struct UNSP *, uint32_t); |
||||
uint32_t get_100_bits_from_table(uint16_t *, struct UNSP *); |
||||
uint32_t get_n_bits_from_table(uint16_t *, uint32_t, struct UNSP *); |
||||
uint32_t get_n_bits_from_tablesize(uint16_t *, struct UNSP *, uint32_t); |
||||
uint32_t get_bb(uint16_t *, uint32_t, struct UNSP *); |
||||
uint32_t get_bitmap(struct UNSP *, uint32_t); |
||||
|
||||
#endif |
||||
#endif |
Loading…
Reference in new issue