diff --git a/README.md b/README.md index 8027669..f9b4755 100644 --- a/README.md +++ b/README.md @@ -145,5 +145,6 @@ v1.0-1.8 * Bug fixes. * Support for [LiveCloudKd](https://github.com/ufrisk/LeechCore/wiki/Device_LiveCloudKd). -latest: +[v2.2](https://github.com/ufrisk/LeechCore/releases/tag/v2.2) * Bug fixes. +* Minor API additions. diff --git a/includes/leechcore.h b/includes/leechcore.h index 80053a4..6d3ce5c 100644 --- a/includes/leechcore.h +++ b/includes/leechcore.h @@ -14,7 +14,7 @@ // (c) Ulf Frisk, 2020 // Author: Ulf Frisk, pcileech@frizk.net // -// Header Version: 2.1 +// Header Version: 2.2 // #ifndef __LEECHCORE_H__ @@ -309,6 +309,8 @@ EXPORTED_FUNCTION BOOL LcWrite( #define LC_OPT_CORE_VERSION_MINOR 0x4000000600000000 // R #define LC_OPT_CORE_VERSION_REVISION 0x4000000700000000 // R #define LC_OPT_CORE_ADDR_MAX 0x1000000800000000 // R +#define LC_OPT_CORE_STATISTICS_CALL_COUNT 0x4000000900000000 // R [lo-dword: LC_STATISTICS_ID_*] +#define LC_OPT_CORE_STATISTICS_CALL_TIME 0x4000000a00000000 // R [lo-dword: LC_STATISTICS_ID_*] #define LC_OPT_MEMORYINFO_VALID 0x0200000100000000 // R #define LC_OPT_MEMORYINFO_FLAG_32BIT 0x0200000300000000 // R @@ -341,6 +343,7 @@ EXPORTED_FUNCTION BOOL LcWrite( #define LC_OPT_FPGA_VERSION_MINOR 0x0300008300000000 // R #define LC_OPT_FPGA_ALGO_TINY 0x0300008400000000 // RW - 1/0 use tiny 128-byte/tlp read algorithm. #define LC_OPT_FPGA_ALGO_SYNCHRONOUS 0x0300008500000000 // RW - 1/0 use synchronous (old) read algorithm. +#define LC_OPT_FPGA_CFGSPACE_XILINX 0x0300008600000000 // RW - [lo-dword: register address in bytes] [bytes: 0-3: data, 4-7: byte_enable(if wr/set); top bit = cfg_mgmt_wr_rw1c_as_rw] #define LC_CMD_FPGA_WRITE_TLP 0x0000010100000000 // R #define LC_CMD_FPGA_LISTEN_TLP 0x0000010200000000 // R diff --git a/includes/lib32/leechcore.lib b/includes/lib32/leechcore.lib index 894b161..9fad93b 100644 Binary files a/includes/lib32/leechcore.lib and b/includes/lib32/leechcore.lib differ diff --git a/includes/lib64/leechcore.lib b/includes/lib64/leechcore.lib index 1a283d2..637426f 100644 Binary files a/includes/lib64/leechcore.lib and b/includes/lib64/leechcore.lib differ diff --git a/leechagent/version.h b/leechagent/version.h index d677f76..ae7cdb3 100644 --- a/leechagent/version.h +++ b/leechagent/version.h @@ -2,9 +2,9 @@ #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_MAJOR 2 -#define VERSION_MINOR 1 -#define VERSION_REVISION 5 -#define VERSION_BUILD 18 +#define VERSION_MINOR 2 +#define VERSION_REVISION 0 +#define VERSION_BUILD 19 #define VER_FILE_DESCRIPTION_STR "LeechAgent Memory Acquisition Service" #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD diff --git a/leechcore/device_fpga.c b/leechcore/device_fpga.c index 49b33db..d1b1b49 100644 --- a/leechcore/device_fpga.c +++ b/leechcore/device_fpga.c @@ -963,7 +963,7 @@ BOOL DeviceFPGA_ConfigWrite(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ WORD wBaseAddr, } /* -* Write a single DWORD to the FPGA bistream v4.2 "shadow" PCIe configuration space. +* Write a number of DWORDs to the FPGA bistream v4.2 "shadow" PCIe configuration space. * -- ctx * -- wBaseAddr * -- pb @@ -971,7 +971,7 @@ BOOL DeviceFPGA_ConfigWrite(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ WORD wBaseAddr, * -- return */ _Success_(return) -BOOL DeviceFPGA_PCIeCfgSpaceWrite(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ WORD wBaseAddr, _In_ PBYTE pb, _In_ DWORD cb) +BOOL DeviceFPGA_PCIeCfgSpaceShadowWrite(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ WORD wBaseAddr, _In_ PBYTE pb, _In_ DWORD cb) { BOOL fReturn = FALSE; BYTE pbTx[0x2000]; @@ -1002,14 +1002,17 @@ BOOL DeviceFPGA_PCIeCfgSpaceWrite(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ WORD wBase * system to read any custom user-provided "shadow" configuration space. * -- ctx * -- pb = only the 1st 0x200 bytes are read +* -- raSingleDW = Config space register address (in DWORD) to read single DWORD +* value from; to read 0x0; enable by set topmost bit. +* -- return */ _Success_(return) -BOOL DeviceFPGA_PCIeCfgSpaceRead(_In_ PDEVICE_CONTEXT_FPGA ctx, _Out_writes_(0x200) PBYTE pb) +BOOL DeviceFPGA_PCIeCfgSpaceCoreRead(_In_ PDEVICE_CONTEXT_FPGA ctx, _Out_writes_(0x200) PBYTE pb, _In_opt_ DWORD raSingleDW) { BYTE pbTxLockEnable[] = { 0x04, 0x00, 0x04, 0x00, 0x80, 0x02, 0x21, 0x77 }; BYTE pbTxLockDisable[] = { 0x00, 0x00, 0x04, 0x00, 0x80, 0x02, 0x21, 0x77 }; BYTE pbTxReadEnable[] = { 0x01, 0x00, 0x01, 0x00, 0x80, 0x02, 0x21, 0x77 }; - BYTE pbTxReadAddress[] = { 0x00, 0x00, 0xff, 0x03, 0x80, 0x14, 0x21, 0x77 }; + BYTE pbTxAddress[] = { 0x00, 0x00, 0xff, 0x03, 0x80, 0x14, 0x21, 0x77 }; BYTE pbTxResultMeta[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x11, 0x77 }; BYTE pbTxResultDataLo[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x11, 0x77 }; BYTE pbTxResultDataHi[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x11, 0x77 }; @@ -1019,21 +1022,33 @@ BOOL DeviceFPGA_PCIeCfgSpaceRead(_In_ PDEVICE_CONTEXT_FPGA ctx, _Out_writes_(0x2 PDWORD pdwData; WORD wDWordAddr, oDWord, wAddr = 0; ZeroMemory(pb, 0x200); - for(wDWordAddr = 0; wDWordAddr < 0x200; wDWordAddr += 32) { + for(wDWordAddr = 0; wDWordAddr < 0x80; wDWordAddr += 32) { // 0x80 * sizeof(DWORD) == 0x200 // enable read/write lock (instruction serialization) cbRxTx = 0; memcpy(pbRxTx + cbRxTx, pbTxLockEnable, 8); cbRxTx += 8; for(oDWord = 0; oDWord < 32; oDWord++) { - // WRITE request setup (address) - pbTxReadAddress[0] = (wDWordAddr + oDWord) & 0xff; - pbTxReadAddress[1] = ((wDWordAddr + oDWord) >> 8) & 0x03; - memcpy(pbRxTx + cbRxTx, pbTxReadAddress, 8); cbRxTx += 8; - // WRITE read enable bit - memcpy(pbRxTx + cbRxTx, pbTxReadEnable, 8); cbRxTx += 8; + // NB! read config space DWORD _TWO_ times on 1st read in + // batch required to clear any lingering register data. + for(i = 0; (i < 2) && (!i || !oDWord); i++) { + // WRITE request setup (address) + if(raSingleDW) { + // set address: single dword read + pbTxAddress[0] = raSingleDW & 0xff; + pbTxAddress[1] = (raSingleDW >> 8) & 0x03; + } else { + // set address: normal (full config space read) + pbTxAddress[0] = (wDWordAddr + oDWord) & 0xff; + pbTxAddress[1] = ((wDWordAddr + oDWord) >> 8) & 0x03; + } + memcpy(pbRxTx + cbRxTx, pbTxAddress, 8); cbRxTx += 8; + // WRITE read enable bit + memcpy(pbRxTx + cbRxTx, pbTxReadEnable, 8); cbRxTx += 8; + } // READ result memcpy(pbRxTx + cbRxTx, pbTxResultMeta, 8); cbRxTx += 8; memcpy(pbRxTx + cbRxTx, pbTxResultDataLo, 8); cbRxTx += 8; memcpy(pbRxTx + cbRxTx, pbTxResultDataHi, 8); cbRxTx += 8; + if(raSingleDW) { break; } } // disable read/write lock memcpy(pbRxTx + cbRxTx, pbTxLockDisable, 8); cbRxTx += 8; @@ -1070,10 +1085,69 @@ BOOL DeviceFPGA_PCIeCfgSpaceRead(_In_ PDEVICE_CONTEXT_FPGA ctx, _Out_writes_(0x2 *(PBYTE)(pb + wAddr + oAddr + 0) = (dwData >> 16) & 0xff; } } + if(raSingleDW) { break; } } return TRUE; } +/* +* Read a single DWORD from the device PCIe configuration space controlled by +* the Xilinx PCIe IP core. +* -- ctx +* -- dwaSingleDW = byte address to read; DWORD aligned; max 0x200. +* -- pdwResultDW +* -- return +*/ +_Success_(return) +BOOL DeviceFPGA_PCIeCfgSpaceCoreReadDWORD(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ DWORD dwaSingleDW, _Out_ PDWORD pdwResultDW) +{ + BYTE pb[0x200]; + if((dwaSingleDW % 4) || dwaSingleDW >= 0x200) { return FALSE; } + if(!DeviceFPGA_PCIeCfgSpaceCoreRead(ctx, pb, 0x80000000 | (dwaSingleDW >> 2))) { return FALSE; } + *pdwResultDW = *(PDWORD)(pb + dwaSingleDW); + return TRUE; +} + +/* +* Write a single DWORD from the device PCIe configuration space controlled by +* the Xilinx PCIe IP core. +* -- ctx +* -- dwaSingleDW = byte address to write; DWORD aligned; max 0x200. +* -- dwByteEnable = byte enable of dwDWORD (set to '0x01010101') to enable all. +* -- dwValue +* -- return +*/ +_Success_(return) +BOOL DeviceFPGA_PCIeCfgSpaceCoreWriteDWORD(_In_ PDEVICE_CONTEXT_FPGA ctx, _In_ DWORD dwaSingleDW, _In_ DWORD dwByteEnable, _In_ DWORD dwValue) +{ + BYTE pbRxTx[0x1000]; + DWORD status, cbRxTx = 0; + BYTE pbTxLockEnable[] = { 0x04, 0x00, 0x04, 0x00, 0x80, 0x02, 0x21, 0x77 }; + BYTE pbTxLockDisable[] = { 0x00, 0x00, 0x04, 0x00, 0x80, 0x02, 0x21, 0x77 }; + BYTE pbTxWriteEnable[] = { 0x02, 0x00, 0x02, 0x00, 0x80, 0x02, 0x21, 0x77 }; + BYTE pbTxAddress[] = { 0x00, 0x00, 0xff, 0xff, 0x80, 0x14, 0x21, 0x77 }; + BYTE pbTxDataLo[] = { 0x00, 0x00, 0xff, 0xff, 0x80, 0x10, 0x21, 0x77 }; + BYTE pbTxDataHi[] = { 0x00, 0x00, 0xff, 0xff, 0x80, 0x12, 0x21, 0x77 }; + if((dwaSingleDW % 4) || dwaSingleDW >= 0x200) { return FALSE; } + pbTxAddress[0] = (dwaSingleDW >> 2) & 0xff; + pbTxAddress[1] = ((dwaSingleDW >> 10) & 0x03) | (dwByteEnable & 0x80000000 ? 0x08 : 0) | + (dwByteEnable & 0x000000ff ? 0x10 : 0) | (dwByteEnable & 0x0000ff00 ? 0x20 : 0) | + (dwByteEnable & 0x00ff0000 ? 0x40 : 0) | (dwByteEnable & 0x7f000000 ? 0x80 : 0); + pbTxDataLo[0] = (BYTE)(dwValue >> 0); + pbTxDataLo[1] = (BYTE)(dwValue >> 8); + pbTxDataHi[0] = (BYTE)(dwValue >> 12); + pbTxDataHi[1] = (BYTE)(dwValue >> 16); + memcpy(pbRxTx + cbRxTx, pbTxLockEnable, 8); cbRxTx += 8; // enable read/write lock + memcpy(pbRxTx + cbRxTx, pbTxDataLo, 8); cbRxTx += 8; // data lo + memcpy(pbRxTx + cbRxTx, pbTxDataHi, 8); cbRxTx += 8; // data hi + memcpy(pbRxTx + cbRxTx, pbTxAddress, 8); cbRxTx += 8; // address & byte_enable + memcpy(pbRxTx + cbRxTx, pbTxWriteEnable, 8); cbRxTx += 8; // write/enable bit + memcpy(pbRxTx + cbRxTx, pbTxLockDisable, 8); cbRxTx += 8; // disable read/write lock + // WRITE TxData + status = ctx->dev.pfnFT_WritePipe(ctx->dev.hFTDI, 0x02, pbRxTx, cbRxTx, &cbRxTx, NULL); + return status ? FALSE : TRUE; +} + /* * Sample function for reading the DRP address space of the Xilinx 7-Series Core. * Please consult "DRP Address Map for PCIE_2_1 Library Element Attributes" in @@ -1190,7 +1264,7 @@ VOID DeviceFPGA_ConfigPrint(_In_ PLC_CONTEXT ctxLC, _In_ PDEVICE_CONTEXT_FPGA ct lcprintf(ctxLC, "\n----- PCIe CORE Dynamic Reconfiguration Port (DRP) SIZE: 0x100 BYTES -----\n"); Util_PrintHexAscii(ctxLC, pb, 0x100, 0); } - if(DeviceFPGA_PCIeCfgSpaceRead(ctx, pb)) { + if(DeviceFPGA_PCIeCfgSpaceCoreRead(ctx, pb, 0)) { lcprintf(ctxLC, "\n----- PCIe CONFIGURATION SPACE (no user set values) SIZE: 0x200 BYTES -----\n"); Util_PrintHexAscii(ctxLC, pb, 0x200, 0); } @@ -1971,7 +2045,7 @@ BOOL DeviceFPGA_Command( if(!ppbDataOut || (ctx->wFpgaVersionMajor < 4)) { return FALSE; } if(!(*ppbDataOut = LocalAlloc(LMEM_ZEROINIT, 0x1000))) { return FALSE; } if(pcbDataOut) { *pcbDataOut = 0x1000; }; - return DeviceFPGA_PCIeCfgSpaceRead(ctx, *ppbDataOut); + return DeviceFPGA_PCIeCfgSpaceCoreRead(ctx, *ppbDataOut, 0); case LC_CMD_FPGA_CFGREGCFG: case LC_CMD_FPGA_CFGREGPCIE: if(ctx->wFpgaVersionMajor < 4) { return FALSE; } @@ -2007,7 +2081,7 @@ BOOL DeviceFPGA_Command( if(ctx->wFpgaVersionMajor < 4) { return FALSE; } if((ctx->wFpgaVersionMajor == 4) && (ctx->wFpgaVersionMinor == 2)) { return FALSE; } if(pbDataIn || !cbDataIn || !(cbDataIn % 4) || (cbDataIn > 0x1000)) { return FALSE; } - return DeviceFPGA_PCIeCfgSpaceWrite(ctx, qwOptionLo & 0x3fff, pbDataIn, cbDataIn); + return DeviceFPGA_PCIeCfgSpaceShadowWrite(ctx, qwOptionLo & 0x3fff, pbDataIn, cbDataIn); case LC_CMD_FPGA_CFGREG_DEBUGPRINT: DeviceFPGA_ConfigPrint(ctxLC, ctx); return TRUE; @@ -2070,6 +2144,9 @@ BOOL DeviceFPGA_GetOption(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWO case LC_OPT_FPGA_ALGO_SYNCHRONOUS: *pqwValue = ctx->async.fEnabled ? 1 : 0; return TRUE; + case LC_OPT_FPGA_CFGSPACE_XILINX: + *pqwValue = 0; + return DeviceFPGA_PCIeCfgSpaceCoreReadDWORD(ctx, (DWORD)fOption, (PDWORD)pqwValue); } return FALSE; } @@ -2110,6 +2187,8 @@ BOOL DeviceFPGA_SetOption(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _In_ QWORD case LC_OPT_FPGA_ALGO_SYNCHRONOUS: ctx->async.fEnabled = (qwValue && ctx->dev.pfnFT_ReleaseOverlapped) ? TRUE : FALSE; return TRUE; + case LC_OPT_FPGA_CFGSPACE_XILINX: + return DeviceFPGA_PCIeCfgSpaceCoreWriteDWORD(ctx, (DWORD)fOption, qwValue >> 32, (DWORD)qwValue); } return FALSE; } diff --git a/leechcore/leechcore.c b/leechcore/leechcore.c index 3db4654..e793e71 100644 --- a/leechcore/leechcore.c +++ b/leechcore/leechcore.c @@ -786,12 +786,12 @@ EXPORTED_FUNCTION BOOL LcRead(_In_ HANDLE hLC, _In_ QWORD pa, _In_ DWORD cb, _Ou if(cb == 0) { return TRUE; } cMEMs = ((pa & 0xfff) + cb + 0xfff) >> 12; if(cMEMs == 0) { return FALSE; } - fFirst = (pa & 0xfff) != 0; + fFirst = (pa & 0xfff) || (cb < 0x1000); fLast = (cMEMs > 1) && ((pa + cb) & 0xfff); f = LcAllocScatter3( fFirst ? pbFirst : NULL, fLast ? pbLast : NULL, - cb - (pa & 0xfff), + (fFirst && (cMEMs == 1)) ? 0 : (cb - (pa & 0xfff)), pb + (pa & 0xfff), (DWORD)cMEMs, &ppMEMs @@ -807,7 +807,7 @@ EXPORTED_FUNCTION BOOL LcRead(_In_ HANDLE hLC, _In_ QWORD pa, _In_ DWORD cb, _Ou } if(fFirst) { o = pa & 0xfff; - memcpy(pb, ppMEMs[0]->pb + o, 0x1000 - (SIZE_T)o); + memcpy(pb, ppMEMs[0]->pb + o, min(cb, 0x1000 - (SIZE_T)o)); } if(fLast) { o = ppMEMs[cMEMs - 1]->qwA; @@ -974,7 +974,7 @@ BOOL LcGetOption_DoWork(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWORD { QWORD v = 0; *pqwValue = 0; - switch(fOption) { + switch(fOption & 0xffffffff00000000) { case LC_OPT_CORE_PRINTF_ENABLE: *pqwValue = ctxLC->fPrintf[LC_PRINTF_ENABLE] ? 1 : 0; return TRUE; @@ -999,6 +999,14 @@ BOOL LcGetOption_DoWork(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWORD case LC_OPT_CORE_ADDR_MAX: *pqwValue = LcMemMap_GetMaxAddress(ctxLC); return TRUE; + case LC_OPT_CORE_STATISTICS_CALL_COUNT: + if((DWORD)fOption > LC_STATISTICS_ID_MAX) { return FALSE; } + *pqwValue = ctxLC->CallStat.Call[(DWORD)fOption].c; + return TRUE; + case LC_OPT_CORE_STATISTICS_CALL_TIME: + if((DWORD)fOption > LC_STATISTICS_ID_MAX) { return FALSE; } + *pqwValue = ctxLC->CallStat.Call[(DWORD)fOption].tm; + return TRUE; } if(ctxLC->pfnGetOption) { return ctxLC->pfnGetOption(ctxLC, fOption, pqwValue); diff --git a/leechcore/leechcore.h b/leechcore/leechcore.h index 80053a4..6d3ce5c 100644 --- a/leechcore/leechcore.h +++ b/leechcore/leechcore.h @@ -14,7 +14,7 @@ // (c) Ulf Frisk, 2020 // Author: Ulf Frisk, pcileech@frizk.net // -// Header Version: 2.1 +// Header Version: 2.2 // #ifndef __LEECHCORE_H__ @@ -309,6 +309,8 @@ EXPORTED_FUNCTION BOOL LcWrite( #define LC_OPT_CORE_VERSION_MINOR 0x4000000600000000 // R #define LC_OPT_CORE_VERSION_REVISION 0x4000000700000000 // R #define LC_OPT_CORE_ADDR_MAX 0x1000000800000000 // R +#define LC_OPT_CORE_STATISTICS_CALL_COUNT 0x4000000900000000 // R [lo-dword: LC_STATISTICS_ID_*] +#define LC_OPT_CORE_STATISTICS_CALL_TIME 0x4000000a00000000 // R [lo-dword: LC_STATISTICS_ID_*] #define LC_OPT_MEMORYINFO_VALID 0x0200000100000000 // R #define LC_OPT_MEMORYINFO_FLAG_32BIT 0x0200000300000000 // R @@ -341,6 +343,7 @@ EXPORTED_FUNCTION BOOL LcWrite( #define LC_OPT_FPGA_VERSION_MINOR 0x0300008300000000 // R #define LC_OPT_FPGA_ALGO_TINY 0x0300008400000000 // RW - 1/0 use tiny 128-byte/tlp read algorithm. #define LC_OPT_FPGA_ALGO_SYNCHRONOUS 0x0300008500000000 // RW - 1/0 use synchronous (old) read algorithm. +#define LC_OPT_FPGA_CFGSPACE_XILINX 0x0300008600000000 // RW - [lo-dword: register address in bytes] [bytes: 0-3: data, 4-7: byte_enable(if wr/set); top bit = cfg_mgmt_wr_rw1c_as_rw] #define LC_CMD_FPGA_WRITE_TLP 0x0000010100000000 // R #define LC_CMD_FPGA_LISTEN_TLP 0x0000010200000000 // R diff --git a/leechcore/oscompatibility.h b/leechcore/oscompatibility.h index 0d254fc..1c2fe64 100644 --- a/leechcore/oscompatibility.h +++ b/leechcore/oscompatibility.h @@ -122,7 +122,7 @@ typedef struct tdEXCEPTION_RECORD64 { CHAR sz[152]; } EXCEPTION_RECORD64 #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) #define strnlen_s(s, maxcount) (strnlen(s, maxcount)) #define strcpy_s(dst, len, src) (strncpy(dst, src, len)) -#define strncpy_s(dst, len, src, srclen) (strncpy(dst, src, len)) +#define strncpy_s(dst, len, src, srclen) (strncpy(dst, src, min(len, srclen))) #define strcat_s(dst, len, src) (strcat(dst, src)) #define strncat_s(dst, len, src, srclen) (strncat(dst, src, srclen)) #define _stricmp(s1, s2) (strcasecmp(s1, s2)) diff --git a/leechcore/version.h b/leechcore/version.h index c9bdb80..00ded7f 100644 --- a/leechcore/version.h +++ b/leechcore/version.h @@ -2,9 +2,9 @@ #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_MAJOR 2 -#define VERSION_MINOR 1 -#define VERSION_REVISION 5 -#define VERSION_BUILD 18 +#define VERSION_MINOR 2 +#define VERSION_REVISION 0 +#define VERSION_BUILD 19 #define VER_FILE_DESCRIPTION_STR "LeechCore Memory Acquisition Library" #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD diff --git a/leechcorepyc/version.h b/leechcorepyc/version.h index 74f1dc0..ff7277b 100644 --- a/leechcorepyc/version.h +++ b/leechcorepyc/version.h @@ -2,9 +2,9 @@ #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_MAJOR 2 -#define VERSION_MINOR 1 -#define VERSION_REVISION 5 -#define VERSION_BUILD 18 +#define VERSION_MINOR 2 +#define VERSION_REVISION 0 +#define VERSION_BUILD 19 #define VER_FILE_DESCRIPTION_STR "LeechCore Memory Acquisition Library : Python API" #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD