Compare commits

...

71 commits

Author SHA1 Message Date
vit9696
4bee991c94 Implement custom LZMA dictionary size support, fixes #154 2018-12-30 18:37:27 +03:00
vit9696
e6f84f9f7d Version bump 2018-06-24 17:07:52 +03:00
vit9696
35c207dd8c More proper solution to #137 2018-06-23 19:46:56 +03:00
vit9696
c4567dcffc Attempt to workaround #137 2018-06-23 00:39:51 +03:00
vit9696
4bb759780f Unify version scheme 2018-05-22 00:43:34 +03:00
vit9696
8ea96ffd5d Support replacing raw sections and ffs via -asis 2018-05-21 10:07:33 +03:00
vit9696
e5d868977e Deploy as prerelease to avoid confusion 2018-05-20 00:02:35 +03:00
vit9696
65263f1000 Allow subguid matching for UEFIReplace 2018-05-19 23:53:21 +03:00
vit9696
dd90367387 Fix recursion in UEFIReplace 2018-05-19 23:35:57 +03:00
vit9696
b5961a7155 Add -o / --output flag to UEFIPatch 2018-05-19 18:55:51 +03:00
vit9696
8db52ea51a Implement replace all and add -o (--output) path to UEFIReplace 2018-05-19 18:35:38 +03:00
vit9696
63e40c058a Increment version 2018-05-08 21:49:11 +03:00
vit9696
f507d71ead Backport decompression updates from new_engine 2018-05-08 19:22:07 +03:00
vit9696
b3f7beb236 Initial Windows build support 2018-05-08 02:28:03 +03:00
vit9696
f321a6c7a8 Add misc patches unrelated to Intel PowerManagement 2018-05-07 22:12:50 +03:00
vit9696
66c9d4a2cf Implement external patches.txt path for UEFIPatch 2018-05-07 22:01:17 +03:00
vit9696
f383646033 Fix UEFITool path on Linux 2018-05-07 21:42:03 +03:00
vit9696
912a1b25b2 Fix compiler warning, closes #121 2018-05-07 21:37:44 +03:00
vit9696
3395cc7a1a Add Linux x86-64 CI support 2018-05-07 21:36:24 +03:00
vit9696
e25ed49b27 Do not try to rebase removed sections, fixes #92 2018-05-07 08:01:09 +03:00
vit9696
3993bd7090 Improve descriptor version handling 2018-05-06 23:28:52 +03:00
vit9696
acb1a4d099 Fix Intel descriptor version parsing at reading 2018-05-06 15:29:08 +03:00
vit9696
03274ff47c Properly read Intel descriptor version, thx @platomav 2018-05-06 15:11:21 +03:00
vit9696
539408c667 Recognise B360MHD3.F3 descriptor version 2018-05-06 11:31:39 +03:00
vit9696
5e81b20c85 Version bump 2018-05-04 21:49:56 +03:00
vit9696
dd28665644 Remove legacy UEFIFind and UEFIExtract in favour of new_engine branch 2018-05-04 21:42:54 +03:00
vit9696
fe13f1efe9 Backport TianoDecompress fix for Xcode (https://bugzilla.tianocore.org/show_bug.cgi?id=635) 2018-05-04 20:46:06 +03:00
vit9696
26b40c229a Merge pull request #130 from vit9696/ci-master
Travis Mac
2018-05-04 06:52:01 +03:00
vit9696
7da3f6b793 Add deploy key 2018-05-04 06:40:04 +03:00
vit9696
3284737952 Implement mac builds with deploy 2018-05-03 22:27:40 +03:00
vit9696
fd4d75957e Fix rebuild reversion 2018-05-03 20:41:27 +03:00
Alex Matrosov
88ed04cd4c Merge pull request #128 from vit9696/recover-skylake
Recover Skylake patches
2018-05-01 20:04:25 -07:00
vit9696
462f693ad6 Recover Skylake patches 2018-05-01 23:27:35 +03:00
Alex Matrosov
a5ce9ab3d9 bugfix 2018-04-29 22:38:54 -07:00
Alex Matrosov
956a804dd5 Merge pull request #126 from HackingThings/master
Fix for EC region parse
2018-04-14 16:04:57 -07:00
HackingThings
dcdb85497d Fix EC region parse
Fixing Copy&Paste bug
2018-04-14 10:40:31 -07:00
Alex Matrosov
ea5ae2f2c8 fixed rebase PEI files with nonstandard alignment 2018-02-25 15:40:14 -08:00
Alex Matrosov
341ee144f9 Merge pull request #113 from interferenc/master
Fixed patches for Skylake-X
2018-02-22 11:59:43 -08:00
Marton Farago
50ff6dc038 Fixed patches for Skylake-X
D71C8BA4-4AF2-4D0D-B1BA-F2409F0C20D3 is a completly unrelated GUID (UncoreInitPei), so while it contains a code block that looks like an MSR 0xE2 lock, that has nothing to do with it.

3FFCAE95-23CF-4967-94F5-16352F68E43B has a better patch that just jumps over the whole lock enforcing block

01359D99-9446-456D-ADA4-50A711C03ADA also needs a patch, this runs on wake from S3 sleep and lock the register again if not patched.
2018-02-15 07:39:34 +01:00
Cr4sh
df95f0755c multiple fixes 2018-02-15 06:04:34 +03:00
Alex Matrosov
9d623c91e6 fix for #99 2018-01-22 23:58:29 -08:00
Alex Matrosov
3ffdae1123 0.22.1 multiple FFSv3 support fixes, thanks to @osresearch
+ multiple FFSv3 support fixes, thanks to @osresearch
+ fixed removal of FFS files with opposite EP bit value
+ disabled creation of large sections (too buggy now, will be fixed later)
2017-12-10 21:54:50 -08:00
Alex Matrosov
73019876cf add FFSv3 support with large files and large sections 2017-12-10 16:54:40 -08:00
Alex Matrosov
75225ecc28 Merge pull request #76 from mxxxc/master
Add UEFIReplace.
2017-05-06 17:24:47 -07:00
Mark
5ba63418bd Add UEFIReplace. 2017-04-14 03:24:24 +02:00
Dmytro Oleksiuk
dbeda3fc9d Merge pull request #69 from adriandumitru/Develop
Add Kaby Lake support.
2017-02-12 10:23:06 +03:00
Adrian Dumitru
b700177e4a Add Kaby Lake support. 2017-01-25 00:30:53 +02:00
Alex Matrosov
8cfd93c8eb Update patches.txt 2016-08-21 15:48:13 -07:00
Nikolaj Schlej
d54f215e67 Forgot to bump UP version 2015-11-12 09:38:14 +01:00
Nikolaj Schlej
19cc031244 UT 0.21.5 /UP 0.3.9 untested
- fixed various crashes reported in #39
- changes aren't tested yet, please don't use until #39 is fixed
2015-11-12 09:37:38 +01:00
Nikolaj Schlej
7ebbc58b9b UT 0.21.4 / UP 0.3.8
- fixed a bug introduced in 0.21.3 commit
2015-10-04 22:28:44 +02:00
Nikolaj Schlej
9d0bcd0bed Fix a compiler warning 2015-10-04 22:05:38 +02:00
Nikolaj Schlej
1ab52fde35 UT 0.21.3 / UP 0.3.7
- solved a bug with Gigabyte-specific descriptor settings (BIOS region
has size of the whole image), thanks to lordkag for #37
2015-10-04 21:58:44 +02:00
Nikolaj Schlej
388dd25093 UT 0.21.2
- fixed a bug with tailed files extraction and replacing (#35)
- fixed a bug with wrong source of padding after all Intel image regions
(#34)
2015-10-02 09:38:30 +02:00
Nikolaj Schlej
ed038c21bf Corrected #34
- padding data was a part of the image, now BIOS region
2015-10-01 08:24:35 +02:00
Nikolaj Schlej
93881e4892 Corrected EC region placement 2015-09-12 21:40:45 +02:00
Nikolaj Schlej
4e8431b169 UT 0.21.1
- added replace action for paddings
- fixed a rare visual bug (wrong image sizes in reconstructRegion
messages)
- parts of the new flash region map are defined a bit better
2015-09-12 21:01:42 +02:00
Nikolaj Schlej
9c7c94702d Replace action for paddings
- and a very small visual bugfix
2015-09-12 20:46:21 +02:00
Nikolaj Schlej
e5cf61f89a Small fixes of FLASH_DESCRIPTOR_REGION_SECTION definition 2015-09-12 19:44:59 +02:00
Nikolaj Schlej
8a14965463 Spellchecking
Corrections of issue #32
2015-09-08 08:54:42 +02:00
Nikolaj Schlej
c286459676 UP 0.3.6
- changed version number due to rebuild with engine version 0.21.0
2015-09-06 23:51:50 +02:00
Nikolaj Schlej
aa80837bf5 UT 0.21.0
- added support for new Intel descriptor type, based on
[this](http://review.coreboot.org/gitweb?p=coreboot.git;a=commit;h=1f7fd720c81755144423f2d4062c39cc651adc0a)
coreboot commit, thanks to lordkag for issue #32
- solved a bug with incorrect volume free space item placement during
volume replace, now works as expected
- solved an issue with incorrect Aptio capsule parsing introduced in
0.20.8
2015-09-06 23:46:26 +02:00
Nikolaj Schlej
9c4ddbec62 UT 0.20.8
- data after the latest region of Intel image is in tree now
- added Intel, Lenovo and Toshiba-specific capsule GUIDs to the list of
known GUIDs
- fixed bogus "File with invalid size" message while working on almost
full volumes
- pressing Cancel on "Open in new window" dialog now works as expected

Big thanks to Lordkag for spotting most of the issues (#31).
2015-08-30 10:52:19 +02:00
Nikolaj Schlej
63e5a4dd1c UT 0.20.7
- added "Open in new window..." action
2015-08-13 20:28:19 +02:00
Nikolaj Schlej
1109e44379 Create LICENSE.md 2015-08-11 18:12:12 +02:00
Nikolaj Schlej
c5fec376f7 Engine 0.20.6
- added support for recalculation of Apple-specific free space offset
value stored in volume's ZeroVector. Thanks to osxreverser for reporting
the issue #29.
- ZeroVectorCRC renamed to AppleCRC32, because it's Apple-specific after
all.
- ParsingData handling removed from old codebase, because it's only
needed for the new engine.
2015-07-05 13:28:53 +02:00
Nikolaj Schlej
d78df75de6 Update version numbers 2015-05-17 10:39:31 +02:00
Nikolaj Schlej
3013398a9d Engine 0.20.5
- raw file header was included twice during reconstruction as region
2015-05-17 10:38:04 +02:00
Nikolaj Schlej
b9b5758d2d Merge pull request #21 from cyrozap/master
Use Travis CI for build testing
2015-03-29 07:36:47 +02:00
cyrozap
351285dfbf Fixing Travis build 2015-03-28 22:20:38 -04:00
cyrozap
92c9754c02 Add Travis CI configuration 2015-03-28 22:15:06 -04:00
48 changed files with 2128 additions and 1224 deletions

28
.appveyor.yml Normal file
View file

@ -0,0 +1,28 @@
image: Visual Studio 2015
environment:
matrix:
- MSYS2_ARCH: i686
MSYSTEM: MINGW32
clone_depth: 10
build_script:
- cd %APPVEYOR_BUILD_FOLDER%
- set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH%
- bash ./unixbuild.sh
deploy:
provider: GitHub
force_update: true
auth_token:
secure: zSJnpSnrKY1NO5RPVBaD/uq7UPyc+GW7ecjPFqEMsLjtnd6H+iNfROdoeuxJgt5T
artifact: Binaries
prerelease: true
on:
appveyor_repo_tag: true
artifacts:
- path: dist\**\*.zip
name: Binaries

8
.gitignore vendored
View file

@ -233,4 +233,10 @@ Makefile
UEFIExtract/UEFIExtract
UEFIFind/UEFIFind
UEFIPatch/UEFIPatch
UEFITool
UEFIReplace/UEFIReplace
UEFITool
.qmake.stash
UEFITool.app/
uefitool_plugin_import.cpp
DerivedData
*.xcodeproj

52
.travis.yml Normal file
View file

@ -0,0 +1,52 @@
language: cpp
matrix:
include:
- os: osx
osx_image: xcode9.2
compiler: clang
script:
- ./unixbuild.sh
deploy:
provider: releases
skip_cleanup: true
file: "dist/*.zip"
file_glob: true
api_key:
secure: "WjYd93lVLKHULBpUXS/WtGrkdXyAwxHOUnLJotyDmQipAQP5Ox7Kj12JwkSJGEmVOEdcbIQJyi0QxPjn1UYbYsAt6Op8zrjnYLS4G4fMdBtcxprWzid85uTW7oAAIFs7ygMVhpzxRKpu70yNb683vbThqNmaOu6RyG9aJOLtPAg="
on:
tags: true
- os: linux
dist: trusty
compiler: clang
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq qt5-default qt5-qmake qtbase5-dev-tools cmake
script:
- ./unixbuild.sh
- os: linux
dist: trusty
compiler: gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq qt5-default qt5-qmake qtbase5-dev-tools cmake
script:
- ./unixbuild.sh
deploy:
provider: releases
skip_cleanup: true
file: "dist/*.zip"
file_glob: true
api_key:
secure: "WjYd93lVLKHULBpUXS/WtGrkdXyAwxHOUnLJotyDmQipAQP5Ox7Kj12JwkSJGEmVOEdcbIQJyi0QxPjn1UYbYsAt6Op8zrjnYLS4G4fMdBtcxprWzid85uTW7oAAIFs7ygMVhpzxRKpu70yNb683vbThqNmaOu6RyG9aJOLtPAg="
on:
tags: true

23
LICENSE.md Normal file
View file

@ -0,0 +1,23 @@
Copyright (c) 2015, Nikolaj Schlej
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -25,7 +25,7 @@ static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize)
{
(void)p; (void) inSize; (void) outSize;
(void)p; (void)inSize; (void)outSize;
return SZ_OK;
}
@ -34,9 +34,9 @@ static ICompressProgress g_ProgressCallback = { &OnProgress };
STATIC
UINT64
EFIAPI
RShiftU64(
UINT64 Operand,
UINT32 Count
RShiftU64 (
UINT64 Operand,
UINT32 Count
)
{
return Operand >> Count;
@ -44,8 +44,8 @@ UINT32 Count
VOID
SetEncodedSizeOfBuf(
UINT64 EncodedSize,
UINT8 *EncodedData
UINT64 EncodedSize,
UINT8* EncodedData
)
{
INT32 Index;
@ -58,13 +58,14 @@ UINT8 *EncodedData
}
}
INT32
EFI_STATUS
EFIAPI
LzmaCompress(
CONST UINT8 *Source,
UINT32 SourceSize,
UINT8 *Destination,
UINT32 *DestinationSize
LzmaCompress (
CONST UINT8 *Source,
UINT32 SourceSize,
UINT8 *Destination,
UINT32 *DestinationSize,
UINT32 DictionarySize
)
{
SRes LzmaResult;
@ -72,14 +73,14 @@ UINT32 *DestinationSize
SizeT propsSize = LZMA_PROPS_SIZE;
SizeT destLen = SourceSize + SourceSize / 3 + 128;
if (*DestinationSize < destLen)
if (*DestinationSize < (UINT32)destLen)
{
*DestinationSize = destLen;
return ERR_BUFFER_TOO_SMALL;
*DestinationSize = (UINT32)destLen;
return EFI_BUFFER_TOO_SMALL;
}
LzmaEncProps_Init(&props);
props.dictSize = LZMA_DICTIONARY_SIZE;
props.dictSize = DictionarySize;
props.level = 9;
props.fb = 273;
@ -87,7 +88,7 @@ UINT32 *DestinationSize
(Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE),
&destLen,
Source,
SourceSize,
(SizeT)SourceSize,
&props,
(UINT8*)Destination,
&propsSize,
@ -96,14 +97,14 @@ UINT32 *DestinationSize
&SzAllocForLzma,
&SzAllocForLzma);
*DestinationSize = destLen + LZMA_HEADER_SIZE;
*DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE);
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
SetEncodedSizeOfBuf(SourceSize, Destination);
if (LzmaResult == SZ_OK) {
return ERR_SUCCESS;
return EFI_SUCCESS;
}
else {
return ERR_INVALID_PARAMETER;
return EFI_INVALID_PARAMETER;
}
}

View file

@ -11,8 +11,8 @@
*/
#ifndef __LZMACOMPRESS_H__
#define __LZMACOMPRESS_H__
#ifndef LZMACOMPRESS_H
#define LZMACOMPRESS_H
#include "SDK/C/Types.h"
#include "../basetypes.h"
@ -21,19 +21,21 @@
extern "C" {
#endif
#define LZMA_DICTIONARY_SIZE 0x800000
#define DEFAULT_LZMA_DICTIONARY_SIZE 0x800000
#define _LZMA_SIZE_OPT
INT32
EFI_STATUS
EFIAPI
LzmaCompress(
const UINT8 *Source,
UINT32 SourceSize,
UINT8 *Destination,
UINT32 *DestinationSize
LzmaCompress (
const UINT8 *Source,
UINT32 SourceSize,
UINT8 *Destination,
UINT32 *DestinationSize,
UINT32 DictionarySize
);
#ifdef __cplusplus
}
#endif
#endif
#endif // LZMACOMPRESS_H

View file

@ -19,10 +19,10 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT64
EFIAPI
LShiftU64(
UINT64 Operand,
UINT32 Count
)
LShiftU64 (
UINT64 Operand,
UINT32 Count
)
{
return Operand << Count;
}
@ -39,12 +39,12 @@ Get the size of the uncompressed buffer by parsing EncodeData header.
@return The size of the uncompressed buffer.
*/
UINT64
GetDecodedSizeOfBuf(
UINT8 *EncodedData
)
GetDecodedSizeOfBuf (
UINT8 *EncodedData
)
{
UINT64 DecodedSize;
INT32 Index;
INT32 Index;
// Parse header
DecodedSize = 0;
@ -85,22 +85,27 @@ DestinationSize and the size of the scratch
buffer was returned ScratchSize.
*/
INT32
EFI_STATUS
EFIAPI
LzmaGetInfo(
CONST VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
)
LzmaGetInfo (
CONST VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
)
{
UInt64 DecodedSize;
UINT64 DecodedSize;
ASSERT(SourceSize >= LZMA_HEADER_SIZE);
(void)SourceSize;
ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize;
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
*DestinationSize = (UINT32)DecodedSize;
return ERR_SUCCESS;
if (DecodedSize <= UINT32_MAX) {
*DestinationSize = (UINT32)DecodedSize;
return ERR_SUCCESS;
}
else {
return ERR_INVALID_PARAMETER;
}
}
/*
@ -122,13 +127,13 @@ the uncompressed buffer is returned Destination.
The source buffer specified by Source is corrupted
(not a valid compressed format).
*/
INT32
EFI_STATUS
EFIAPI
LzmaDecompress(
CONST VOID *Source,
UINT32 SourceSize,
VOID *Destination
)
LzmaDecompress (
CONST VOID *Source,
UINT32 SourceSize,
VOID *Destination
)
{
SRes LzmaResult;
ELzmaStatus Status;

View file

@ -11,8 +11,8 @@
*/
#ifndef __LZMADECOMPRESS_H__
#define __LZMADECOMPRESS_H__
#ifndef LZMADECOMPRESS_H
#define LZMADECOMPRESS_H
#include "../basetypes.h"
#include "SDK/C/LzmaDec.h"
@ -23,13 +23,6 @@ extern "C" {
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
UINT64
EFIAPI
LShiftU64(
UINT64 Operand,
UINT32 Count
);
/*
Given a Lzma compressed source buffer, this function retrieves the size of
the uncompressed buffer and the size of the scratch buffer required
@ -57,12 +50,12 @@ extern "C" {
buffer was returned ScratchSize.
*/
INT32
EFI_STATUS
EFIAPI
LzmaGetInfo(
const VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
LzmaGetInfo (
CONST VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
);
/*
@ -84,15 +77,16 @@ extern "C" {
The source buffer specified by Source is corrupted
(not a valid compressed format).
*/
INT32
EFI_STATUS
EFIAPI
LzmaDecompress(
const VOID *Source,
UINT32 SourceSize,
VOID *Destination
LzmaDecompress (
CONST VOID *Source,
UINT32 SourceSize,
VOID *Destination
);
#ifdef __cplusplus
}
#endif
#endif
#endif // LZMADECOMPRESS_H

View file

@ -69,18 +69,15 @@ PutDword(
STATIC
EFI_STATUS
AllocateMemory (
);
AllocateMemory (VOID);
STATIC
VOID
FreeMemory (
);
FreeMemory (VOID);
STATIC
VOID
InitSlide (
);
InitSlide (VOID);
STATIC
NODE
@ -105,28 +102,23 @@ Split (
STATIC
VOID
InsertNode (
);
InsertNode (VOID);
STATIC
VOID
DeleteNode (
);
DeleteNode (VOID);
STATIC
VOID
GetNextMatch (
);
GetNextMatch (VOID);
STATIC
EFI_STATUS
Encode (
);
Encode (VOID);
STATIC
VOID
CountTFreq (
);
CountTFreq (VOID);
STATIC
VOID
@ -138,8 +130,7 @@ WritePTLen (
STATIC
VOID
WriteCLen (
);
WriteCLen (VOID);
STATIC
VOID
@ -155,8 +146,7 @@ EncodeP (
STATIC
VOID
SendBlock (
);
SendBlock (VOID);
STATIC
VOID
@ -167,18 +157,15 @@ Output (
STATIC
VOID
HufEncodeStart (
);
HufEncodeStart (VOID);
STATIC
VOID
HufEncodeEnd (
);
HufEncodeEnd (VOID);
STATIC
VOID
MakeCrcTable (
);
MakeCrcTable (VOID);
STATIC
VOID
@ -196,8 +183,7 @@ FreadCrc (
STATIC
VOID
InitPutBits (
);
InitPutBits (VOID);
STATIC
VOID
@ -506,17 +492,24 @@ Returns:
UINT32 i;
mText = malloc (WNDSIZ * 2 + MAXMATCH);
if (!mText) return EFI_OUT_OF_RESOURCES;
for (i = 0 ; i < WNDSIZ * 2 + MAXMATCH; i ++) {
mText[i] = 0;
}
mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
mParent = malloc (WNDSIZ * 2 * sizeof(*mParent));
mPrev = malloc (WNDSIZ * 2 * sizeof(*mPrev));
mNext = malloc ((MAX_HASH_VAL + 1) * sizeof(*mNext));
mLevel = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
if (!mLevel) return EFI_OUT_OF_RESOURCES;
mChildCount = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
if (!mChildCount) return EFI_OUT_OF_RESOURCES;
mPosition = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
if (!mPosition) return EFI_OUT_OF_RESOURCES;
mParent = malloc(WNDSIZ * 2 * sizeof(*mParent));
if (!mParent) return EFI_OUT_OF_RESOURCES;
mPrev = malloc(WNDSIZ * 2 * sizeof(*mPrev));
if (!mPrev) return EFI_OUT_OF_RESOURCES;
mNext = malloc((MAX_HASH_VAL + 1) * sizeof(*mNext));
if (!mNext) return EFI_OUT_OF_RESOURCES;
mBufSiz = 16 * 1024U;
while ((mBuf = malloc(mBufSiz)) == NULL) {
mBufSiz = (mBufSiz / 10U) * 9U;

View file

@ -20,8 +20,8 @@ Header file for compression routine.
*/
#ifndef _EFITIANOCOMPRESS_H_
#define _EFITIANOCOMPRESS_H_
#ifndef EFITIANOCOMPRESS_H
#define EFITIANOCOMPRESS_H
#include <string.h>
#include <stdlib.h>
@ -115,4 +115,4 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#endif
#endif // EFITIANOCOMPRESS_H

View file

@ -529,17 +529,24 @@ STATIC
{
UINT32 Index;
mText = malloc (WNDSIZ * 2 + MAXMATCH);
mText = malloc (WNDSIZ * 2 + MAXMATCH);
if (!mText) return EFI_OUT_OF_RESOURCES;
for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
mText[Index] = 0;
}
mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
if (!mLevel) return EFI_OUT_OF_RESOURCES;
mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
if (!mChildCount) return EFI_OUT_OF_RESOURCES;
mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
if (!mPosition) return EFI_OUT_OF_RESOURCES;
mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
if (!mParent) return EFI_OUT_OF_RESOURCES;
mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
if (!mPrev) return EFI_OUT_OF_RESOURCES;
mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
if (!mNext) return EFI_OUT_OF_RESOURCES;
mBufSiz = BLKSIZ;
mBuf = malloc (mBufSiz);

View file

@ -100,10 +100,10 @@ Returns: (VOID)
--*/
{
Sd->mBitBuf = (UINT32)(Sd->mBitBuf << NumOfBits);
Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
while (NumOfBits > Sd->mBitCount) {
Sd->mBitBuf |= (UINT32)(Sd->mSubBitBuf << (NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount)));
Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
if (Sd->mCompSize > 0) {
//

View file

@ -21,8 +21,8 @@ Providing both EFI and Tiano decompress algorithms.
--*/
#ifndef _EFITIANODECOMPRESS_H_
#define _EFITIANODECOMPRESS_H_
#ifndef EFITIANODECOMPRESS_H
#define EFITIANODECOMPRESS_H
#include <string.h>
#include <stdlib.h>
@ -32,110 +32,107 @@ Providing both EFI and Tiano decompress algorithms.
extern "C" {
#endif
typedef struct {
UINT32 CompSize;
UINT32 OrigSize;
} EFI_TIANO_HEADER;
typedef struct EFI_TIANO_HEADER_ {
UINT32 CompSize;
UINT32 OrigSize;
} EFI_TIANO_HEADER;
EFI_STATUS
EFIAPI
EfiTianoGetInfo(
EFI_STATUS
EFIAPI
EfiTianoGetInfo(
const VOID *Source,
UINT32 SrcSize,
UINT32 *DstSize,
UINT32 *ScratchSize
)
/*++
/*++
Routine Description:
Routine Description:
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.GetInfo().
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.GetInfo().
Arguments:
Arguments:
This - The protocol instance pointer
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
DstSize - The size of destination buffer.
ScratchSize - The size of scratch buffer.
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
DstSize - The size of destination buffer.
ScratchSize - The size of scratch buffer.
Returns:
Returns:
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
;
--*/
;
EFI_STATUS
EFIAPI
EfiDecompress(
const VOID *Source,
EFI_STATUS
EFIAPI
EfiDecompress(
const VOID *Source,
UINT32 SrcSize,
VOID *Destination,
UINT32 DstSize,
VOID *Scratch,
UINT32 ScratchSize
)
/*++
);
/*++
Routine Description:
Routine Description:
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
Arguments:
Arguments:
This - The protocol instance pointer
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
Destination - The destination buffer to store the decompressed data
DstSize - The size of destination buffer.
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
ScratchSize - The size of scratch buffer.
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
Destination - The destination buffer to store the decompressed data
DstSize - The size of destination buffer.
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
ScratchSize - The size of scratch buffer.
Returns:
Returns:
EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
;
--*/
;
EFI_STATUS
EFIAPI
TianoDecompress(
const VOID *Source,
EFI_STATUS
EFIAPI
TianoDecompress(
const VOID *Source,
UINT32 SrcSize,
VOID *Destination,
UINT32 DstSize,
VOID *Scratch,
UINT32 ScratchSize
)
/*++
/*++
Routine Description:
Routine Description:
The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
Arguments:
Arguments:
This - The protocol instance pointer
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
Destination - The destination buffer to store the decompressed data
DstSize - The size of destination buffer.
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
ScratchSize - The size of scratch buffer.
Source - The source buffer containing the compressed data.
SrcSize - The size of source buffer
Destination - The destination buffer to store the decompressed data
DstSize - The size of destination buffer.
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
ScratchSize - The size of scratch buffer.
Returns:
Returns:
EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
;
--*/
;
#ifdef __cplusplus
}
#endif
#endif
#endif // EFITIANODECOMPRESS_H

View file

@ -1,49 +0,0 @@
/* uefiextract.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "uefiextract.h"
UEFIExtract::UEFIExtract(QObject *parent) :
QObject(parent)
{
ffsEngine = new FfsEngine(this);
}
UEFIExtract::~UEFIExtract()
{
delete ffsEngine;
}
UINT8 UEFIExtract::init(const QString & path)
{
fileInfo = QFileInfo(path);
if (!fileInfo.exists())
return ERR_FILE_OPEN;
QFile inputFile;
inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly))
return ERR_FILE_OPEN;
QByteArray buffer = inputFile.readAll();
inputFile.close();
return ffsEngine->parseImageFile(buffer);
}
UINT8 UEFIExtract::extract(QString guid)
{
return ffsEngine->dump(ffsEngine->treeModel()->index(0, 0), fileInfo.fileName().append(".dump"), guid);
}

View file

@ -1,43 +0,0 @@
/* uefiextract.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef __UEFIEXTRACT_H__
#define __UEFIEXTRACT_H__
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QDir>
#include <QFileInfo>
#include "../basetypes.h"
#include "../ffsengine.h"
class UEFIExtract : public QObject
{
Q_OBJECT
public:
explicit UEFIExtract(QObject *parent = 0);
~UEFIExtract();
UINT8 init(const QString & path);
UINT8 extract(QString guid = QString());
private:
FfsEngine* ffsEngine;
QFileInfo fileInfo;
};
#endif

View file

@ -1,60 +0,0 @@
/* uefiextract_main.cpp
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <QCoreApplication>
#include <QString>
#include <QStringList>
#include <iostream>
#include "uefiextract.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.setOrganizationName("CodeRush");
a.setOrganizationDomain("coderush.me");
a.setApplicationName("UEFIExtract");
UEFIExtract w;
UINT8 result = ERR_SUCCESS;
UINT32 returned = 0;
if (a.arguments().length() > 32) {
std::cout << "Too many arguments" << std::endl;
return 1;
}
if (a.arguments().length() > 1 ) {
if (w.init(a.arguments().at(1)))
return 1;
if (a.arguments().length() == 2) {
result = w.extract();
if (result)
return 2;
}
else {
for (int i = 2; i < a.arguments().length(); i++) {
result = w.extract(a.arguments().at(i));
if (result)
returned |= (1 << (i - 1));
}
return returned;
}
}
else {
std::cout << "UEFIExtract 0.4.4" << std::endl << std::endl <<
"Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
"Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
return 1;
}
}

View file

@ -1,160 +0,0 @@
/* uefifind.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "uefifind.h"
UEFIFind::UEFIFind(QObject *parent) :
QObject(parent)
{
ffsEngine = new FfsEngine(this);
model = ffsEngine->treeModel();
initDone = false;
}
UEFIFind::~UEFIFind()
{
model = NULL;
delete ffsEngine;
}
UINT8 UEFIFind::init(const QString & path)
{
UINT8 result;
fileInfo = QFileInfo(path);
if (!fileInfo.exists())
return ERR_FILE_OPEN;
QFile inputFile;
inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly))
return ERR_FILE_OPEN;
QByteArray buffer = inputFile.readAll();
inputFile.close();
result = ffsEngine->parseImageFile(buffer);
if (result)
return result;
initDone = true;
return ERR_SUCCESS;
}
QString UEFIFind::guidToQString(const UINT8* guid)
{
const UINT32 u32 = *(const UINT32*)guid;
const UINT16 u16_1 = *(const UINT16*)(guid + 4);
const UINT16 u16_2 = *(const UINT16*)(guid + 6);
const UINT8 u8_1 = *(const UINT8*)(guid + 8);
const UINT8 u8_2 = *(const UINT8*)(guid + 9);
const UINT8 u8_3 = *(const UINT8*)(guid + 10);
const UINT8 u8_4 = *(const UINT8*)(guid + 11);
const UINT8 u8_5 = *(const UINT8*)(guid + 12);
const UINT8 u8_6 = *(const UINT8*)(guid + 13);
const UINT8 u8_7 = *(const UINT8*)(guid + 14);
const UINT8 u8_8 = *(const UINT8*)(guid + 15);
return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11").hexarg2(u32, 8).hexarg2(u16_1, 4).hexarg2(u16_2, 4).hexarg2(u8_1, 2).hexarg2(u8_2, 2)
.hexarg2(u8_3, 2).hexarg2(u8_4, 2).hexarg2(u8_5, 2).hexarg2(u8_6, 2).hexarg2(u8_7, 2).hexarg2(u8_8, 2);
}
UINT8 UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result)
{
QModelIndex root = model->index(0, 0);
QSet<QPair<QModelIndex, QModelIndex> > files;
result.clear();
UINT8 returned = findFileRecursive(root, hexPattern, mode, files);
if (returned)
return returned;
if (count) {
if (files.count())
result.append(QString("%1\n").arg(files.count()));
return ERR_SUCCESS;
}
QPair<QModelIndex, QModelIndex> indexes;
Q_FOREACH(indexes, files) {
QByteArray data = model->header(indexes.first).left(16);
result.append(guidToQString((const UINT8*)data.constData()));
// Special case of freeform subtype GUID files
if (indexes.second.isValid() && model->subtype(indexes.second) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
data = model->header(indexes.second).left(sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION));
result.append(" ").append(guidToQString((const UINT8*)data.constData() + sizeof(EFI_COMMON_SECTION_HEADER)));
}
result.append("\n");
}
return ERR_SUCCESS;
}
UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files)
{
if (!index.isValid())
return ERR_SUCCESS;
if (hexPattern.isEmpty())
return ERR_INVALID_PARAMETER;
// Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length())
return ERR_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
findFileRecursive(index.child(i, index.column()), hexPattern, mode, files);
}
QByteArray data;
if (hasChildren) {
if (mode == SEARCH_MODE_HEADER || mode == SEARCH_MODE_ALL)
data.append(model->header(index));
}
else {
if (mode == SEARCH_MODE_HEADER)
data.append(model->header(index));
else if (mode == SEARCH_MODE_BODY)
data.append(model->body(index));
else
data.append(model->header(index)).append(model->body(index));
}
QString hexBody = QString(data.toHex());
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive);
INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) {
if (offset % 2 == 0) {
if (model->type(index) != Types::File) {
QModelIndex ffs = model->findParentOfType(index, Types::File);
if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID)
files.insert(QPair<QModelIndex, QModelIndex>(ffs, index));
else
files.insert(QPair<QModelIndex, QModelIndex>(ffs, QModelIndex()));
}
else
files.insert(QPair<QModelIndex, QModelIndex>(index, QModelIndex()));
break;
}
offset = regexp.indexIn(hexBody, offset + 1);
}
return ERR_SUCCESS;
}

View file

@ -1,43 +0,0 @@
QT += core
QT -= gui
TARGET = UEFIFind
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEFINES += _CONSOLE _DISABLE_ENGINE_MESSAGES
SOURCES += uefifind_main.cpp \
uefifind.cpp \
../types.cpp \
../descriptor.cpp \
../ffs.cpp \
../ffsengine.cpp \
../peimage.cpp \
../treeitem.cpp \
../treemodel.cpp \
../LZMA/LzmaCompress.c \
../LZMA/LzmaDecompress.c \
../LZMA/SDK/C/LzFind.c \
../LZMA/SDK/C/LzmaDec.c \
../LZMA/SDK/C/LzmaEnc.c \
../Tiano/EfiTianoDecompress.c \
../Tiano/EfiTianoCompress.c \
../Tiano/EfiTianoCompressLegacy.c
HEADERS += uefifind.h \
../basetypes.h \
../descriptor.h \
../gbe.h \
../me.h \
../ffs.h \
../peimage.h \
../types.h \
../ffsengine.h \
../treeitem.h \
../treemodel.h \
../LZMA/LzmaCompress.h \
../LZMA/LzmaDecompress.h \
../Tiano/EfiTianoDecompress.h \
../Tiano/EfiTianoCompress.h

View file

@ -1,72 +0,0 @@
/* uefifind_main.cpp
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <QCoreApplication>
#include <iostream>
#include "uefifind.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.setOrganizationName("CodeRush");
a.setOrganizationDomain("coderush.me");
a.setApplicationName("UEFIFind");
UEFIFind w;
UINT8 result;
if (a.arguments().length() == 5) {
result = w.init(a.arguments().at(4));
if (result)
return result;
// Get search mode
UINT8 mode;
if (a.arguments().at(1) == QString("header"))
mode = SEARCH_MODE_HEADER;
else if (a.arguments().at(1) == QString("body"))
mode = SEARCH_MODE_BODY;
else if (a.arguments().at(1) == QString("all"))
mode = SEARCH_MODE_ALL;
else
return ERR_INVALID_PARAMETER;
// Get result type
bool count;
if (a.arguments().at(2) == QString("list"))
count = false;
else if (a.arguments().at(2) == QString("count"))
count = true;
else
return ERR_INVALID_PARAMETER;
// Go find the supplied pattern
QString found;
result = w.find(mode, count, a.arguments().at(3), found);
if (result)
return result;
// Nothing was found
if (found.isEmpty())
return ERR_ITEM_NOT_FOUND;
// Print result
std::cout << found.toStdString();
return ERR_SUCCESS;
}
else {
std::cout << "UEFIFind 0.3.4" << std::endl << std::endl <<
"Usage: uefifind {header | body | all} {list | count} pattern imagefile\n";
return ERR_INVALID_PARAMETER;
}
}

View file

@ -0,0 +1,37 @@
# Patch string format
# FileGuid SectionType PatchType:FindPatternOrOffset:ReplacePattern
# Please ensure that the latest symbol in patch string is space
# Possible section types:
# PE32 image 10
# Position-independent code 11
# TE Image 12
# DXE Dependency 13
# Version information 14
# User interface string 15
# 16-bit code 16
# Guided freeform 18
# Raw data 19
# PEI Dependency 1B
# SMM Dependency 1C
# Please do not try another section types, it can make the resulting image broken
# Possible patch types:
# P - pattern-based, first parameter is a pattern to find, second - a pattern to replace
# O - offset-based, first parameter is hexadecimal offset, second - a pattern to replace
# Patterns can have . as "any possible value" symbol
#----------------------------------------------------------------------------------
# Set IA32_FEATURE_CONTROL.SGX_LC
#----------------------------------------------------------------------------------
# SiInit | Gemini Lake
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 10 P:B93A0000000F320D00000400:B93A0000000F320D00000600
#----------------------------------------------------------------------------------
# Broken EFI_SIMPLE_POINTER_PROTOCOL implementation patches
# Fixes incorrect pointer position update/click condition on Z87 chips
#----------------------------------------------------------------------------------
# UHCD | ASUS Z87-Pro
580DD900-385D-11D7-883A-00500473D4EB 10 P:807A3200745C807A4000:807A32007506807A4000

View file

@ -34,9 +34,26 @@ F7731B4C-58A2-4DF4-8980-5645D39ECE58 10 P:0FBA6C24380F:0FBA7424380F
# PowerManagement | Sandy Bridge with ME 8.xx, Ivy Bridge
8C783970-F02A-4A4D-AF09-8797A51EEC8D 10 P:75080FBAE80F89442430:EB080FBAE80F89442430
# PowerManagement | New SB-E/IB-E
8C783970-F02A-4A4D-AF09-8797A51EEC8D 10 P:0FBA6C24380F:0FBA7424380F
# CpuPei | Sandy Bridge with ME 7.xx, old SB-E/IB-E
2BB5AFA9-FF33-417B-8497-CB773C2B93BF 10 P:800018EB050D0080:000018EB050D0000
# PpmInitialize | Broadwell-E
3FFCAE95-23CF-4967-94F5-16352F68E43B 10 P:0FBA6C24400F:0FBA7424400F
# SiInit | Skylake
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 10 P:75080D00800000:EB080D00800000
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 12 P:75080D00800000:EB080D00800000
# SiInit | Kaby Lake
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 10 P:81E10080000033C1:9090909090909090
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 12 P:81E10080000033C1:9090909090909090
# PpmInitialize | Skylake-X
3FFCAE95-23CF-4967-94F5-16352F68E43B 10 P:742CB9E2000000:752CB9E2000000
# CpuInitPei | Skylake-X
01359D99-9446-456D-ADA4-50A711C03ADA 12 P:BE0080000023CE0B:BE0000000023CE0B

View file

@ -25,15 +25,15 @@ UEFIPatch::~UEFIPatch()
delete ffsEngine;
}
UINT8 UEFIPatch::patchFromFile(QString path)
UINT8 UEFIPatch::patchFromFile(const QString & path, const QString & patches, const QString & outputPath)
{
QFileInfo patchInfo = QFileInfo("patches.txt");
QFileInfo patchInfo = QFileInfo(patches);
if (!patchInfo.exists())
return ERR_INVALID_FILE;
QFile file;
file.setFileName("patches.txt");
file.setFileName(patches);
if (!file.open(QFile::ReadOnly | QFile::Text))
return ERR_INVALID_FILE;
@ -110,7 +110,7 @@ UINT8 UEFIPatch::patchFromFile(QString path)
return ERR_NOTHING_TO_PATCH;
QFile outputFile;
outputFile.setFileName(path.append(".patched"));
outputFile.setFileName(outputPath);
if (!outputFile.open(QFile::WriteOnly))
return ERR_FILE_WRITE;

View file

@ -33,9 +33,7 @@ public:
explicit UEFIPatch(QObject *parent = 0);
~UEFIPatch();
UINT8 patchFromFile(QString path);
UINT8 patch(QString path, QString fileGuid, QString findPattern, QString replacePattern);
UINT8 patchFromFile(const QString & path, const QString & patches, const QString & outputPath);
private:
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches);
FfsEngine* ffsEngine;

View file

@ -36,6 +36,7 @@ HEADERS += uefipatch.h \
../ffsengine.h \
../treeitem.h \
../treemodel.h \
../version.h \
../LZMA/LzmaCompress.h \
../LZMA/LzmaDecompress.h \
../Tiano/EfiTianoDecompress.h \

View file

@ -1,6 +1,6 @@
/* uefipatch_main.cpp
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
Copyright (c) 2018, LongSoft. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -14,29 +14,48 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <QString>
#include <QStringList>
#include <iostream>
#include <string>
#include "../version.h"
#include "uefipatch.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.setOrganizationName("CodeRush");
a.setOrganizationDomain("coderush.me");
a.setOrganizationName("LongSoft");
a.setOrganizationDomain("longsoft.me");
a.setApplicationName("UEFIPatch");
UEFIPatch w;
UINT8 result = ERR_SUCCESS;
UINT32 argumentsCount = a.arguments().length();
if (argumentsCount == 2) {
result = w.patchFromFile(a.arguments().at(1));
}
else {
std::cout << "UEFIPatch 0.3.4 - UEFI image file patching utility" << std::endl << std::endl <<
"Usage: UEFIPatch image_file" << std::endl << std::endl <<
"Patches will be read from patches.txt file\n";
const QStringList &args = a.arguments();
UINT32 argumentsCount = args.length();
if (argumentsCount < 2) {
std::cout << "UEFIPatch " PROGRAM_VERSION " - UEFI image file patching utility" << std::endl << std::endl <<
"Usage: UEFIPatch image_file [patches.txt] [-o output]" << std::endl << std::endl <<
"Patches will be read from patches.txt file by default\n";
return ERR_SUCCESS;
}
QString inputPath = a.arguments().at(1);
QString patches = "patches.txt";
QString outputPath = inputPath + ".patched";
for (UINT32 i = 2; i < argumentsCount; i++) {
if ((args.at(i) == "-o" || args.at(i) == "--output") && i + 1 < argumentsCount) {
outputPath = args.at(i+1);
i++;
} else if (patches == "patches.txt") {
patches = args.at(i);
} else {
result = ERR_INVALID_PARAMETER;
}
}
if (result == ERR_SUCCESS) {
result = w.patchFromFile(inputPath, patches, outputPath);
}
switch (result) {
case ERR_SUCCESS:
std::cout << "Image patched" << std::endl;
@ -57,7 +76,7 @@ int main(int argc, char *argv[])
std::cout << "Pattern format mismatch" << std::endl;
break;
case ERR_INVALID_FILE:
std::cout << "patches.txt file not found or can't be read" << std::endl;
std::cout << patches.toStdString() << " file not found or can't be read" << std::endl;
break;
case ERR_FILE_OPEN:
std::cout << "Input file not found" << std::endl;

122
UEFIReplace/uefireplace.cpp Normal file
View file

@ -0,0 +1,122 @@
/* uefireplace.cpp
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "uefireplace.h"
UEFIReplace::UEFIReplace(QObject *parent) :
QObject(parent)
{
ffsEngine = new FfsEngine(this);
model = ffsEngine->treeModel();
}
UEFIReplace::~UEFIReplace()
{
delete ffsEngine;
}
UINT8 UEFIReplace::replace(const QString & inPath, const QByteArray & guid, const UINT8 sectionType, const QString & contentPath, const QString & outPath, bool replaceAsIs, bool replaceOnce)
{
QFileInfo fileInfo = QFileInfo(inPath);
if (!fileInfo.exists())
return ERR_FILE_OPEN;
fileInfo = QFileInfo(contentPath);
if (!fileInfo.exists())
return ERR_FILE_OPEN;
QFile inputFile;
inputFile.setFileName(inPath);
if (!inputFile.open(QFile::ReadOnly))
return ERR_FILE_READ;
QByteArray buffer = inputFile.readAll();
inputFile.close();
UINT8 result = ffsEngine->parseImageFile(buffer);
if (result)
return result;
QFile contentFile;
contentFile.setFileName(contentPath);
if (!contentFile.open(QFile::ReadOnly))
return ERR_FILE_READ;
QByteArray contents = contentFile.readAll();
contentFile.close();
result = replaceInFile(model->index(0, 0), guid, sectionType, contents,
replaceAsIs ? REPLACE_MODE_AS_IS : REPLACE_MODE_BODY, replaceOnce);
if (result)
return result;
QByteArray reconstructed;
result = ffsEngine->reconstructImageFile(reconstructed);
if (result)
return result;
if (reconstructed == buffer)
return ERR_NOTHING_TO_PATCH;
QFile outputFile;
outputFile.setFileName(outPath);
if (!outputFile.open(QFile::WriteOnly))
return ERR_FILE_WRITE;
outputFile.resize(0);
outputFile.write(reconstructed);
outputFile.close();
return ERR_SUCCESS;
}
UINT8 UEFIReplace::replaceInFile(const QModelIndex & index, const QByteArray & guid, const UINT8 sectionType, const QByteArray & newData, const UINT8 mode, bool replaceOnce)
{
if (!model || !index.isValid())
return ERR_INVALID_PARAMETER;
bool patched = false;
if (model->subtype(index) == sectionType) {
QModelIndex fileIndex = index;
if (model->type(index) != Types::File)
fileIndex = model->findParentOfType(index, Types::File);
QByteArray fileGuid = model->header(fileIndex).left(sizeof(EFI_GUID));
bool guidMatch = fileGuid == guid;
if (!guidMatch && sectionType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
QByteArray subGuid = model->header(index).mid(sizeof(UINT32), sizeof(EFI_GUID));
guidMatch = subGuid == guid;
}
if (guidMatch && model->action(index) != Actions::Replace) {
UINT8 result = ffsEngine->replace(index, newData, mode);
if (replaceOnce || (result != ERR_SUCCESS && result != ERR_NOTHING_TO_PATCH))
return result;
patched = result == ERR_SUCCESS;
}
}
if (model->rowCount(index) > 0) {
for (int i = 0; i < model->rowCount(index); i++) {
UINT8 result = replaceInFile(index.child(i, 0), guid, sectionType, newData, mode, replaceOnce);
if (result == ERR_SUCCESS) {
patched = true;
if (replaceOnce)
break;
} else if (result != ERR_NOTHING_TO_PATCH) {
return result;
}
}
}
return patched ? ERR_SUCCESS : ERR_NOTHING_TO_PATCH;
}

View file

@ -1,52 +1,41 @@
/* uefifind.h
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
/* uefireplace.h
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef __UEFIFIND_H__
#define __UEFIFIND_H__
#ifndef __UEFIREPLACE_H__
#define __UEFIREPLACE_H__
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QDir>
#include <QStringList>
#include <QFileInfo>
#include <QPair>
#include <QSet>
#include <QString>
#include <QUuid>
#include "../basetypes.h"
#include "../ffsengine.h"
#include "../ffs.h"
#include "../ffsengine.h"
class UEFIFind : public QObject
class UEFIReplace : public QObject
{
Q_OBJECT
public:
explicit UEFIFind(QObject *parent = 0);
~UEFIFind();
explicit UEFIReplace(QObject *parent = 0);
~UEFIReplace();
UINT8 init(const QString & path);
UINT8 find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result);
UINT8 replace(const QString & inPath, const QByteArray & guid, const UINT8 sectionType, const QString & contentPath, const QString & outPath, bool replaceAsIs, bool replaceOnce);
private:
UINT8 findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files);
QString guidToQString(const UINT8* guid);
UINT8 replaceInFile(const QModelIndex & index, const QByteArray & guid, const UINT8 sectionType, const QByteArray & contents, const UINT8 mode, bool replaceOnce);
FfsEngine* ffsEngine;
TreeModel* model;
QFileInfo fileInfo;
bool initDone;
};
#endif

View file

@ -1,14 +1,14 @@
QT += core
QT -= gui
TARGET = UEFIExtract
TARGET = UEFIReplace
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEFINES += _CONSOLE
SOURCES += uefiextract_main.cpp \
uefiextract.cpp \
SOURCES += uefireplace_main.cpp \
uefireplace.cpp \
../types.cpp \
../descriptor.cpp \
../ffs.cpp \
@ -25,7 +25,7 @@ SOURCES += uefiextract_main.cpp \
../Tiano/EfiTianoCompress.c \
../Tiano/EfiTianoCompressLegacy.c
HEADERS += uefiextract.h \
HEADERS += uefireplace.h \
../basetypes.h \
../descriptor.h \
../gbe.h \
@ -36,8 +36,8 @@ HEADERS += uefiextract.h \
../ffsengine.h \
../treeitem.h \
../treemodel.h \
../version.h \
../LZMA/LzmaCompress.h \
../LZMA/LzmaDecompress.h \
../Tiano/EfiTianoDecompress.h \
../Tiano/EfiTianoCompress.h
../Tiano/EfiTianoCompress.h

View file

@ -0,0 +1,98 @@
/* uefireplace_main.cpp
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <QCoreApplication>
#include <QString>
#include <QStringList>
#include <iostream>
#include "../version.h"
#include "uefireplace.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.setOrganizationName("LongSoft");
a.setOrganizationDomain("longsoft.me");
a.setApplicationName("UEFIReplace");
UEFIReplace r;
UINT8 result = ERR_SUCCESS;
QStringList args = a.arguments();
if (args.length() < 5) {
std::cout << "UEFIReplace " PROGRAM_VERSION " - UEFI image file replacement utility" << std::endl << std::endl <<
"Usage: UEFIReplace image_file guid section_type contents_file [-o output] [-all] [-asis]" << std::endl;
return ERR_SUCCESS;
}
QUuid uuid = QUuid(args.at(2));
QByteArray guid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));
bool converted;
UINT8 sectionType = (UINT8)args.at(3).toUShort(&converted, 16);
if (!converted) {
result = ERR_INVALID_PARAMETER;
} else {
QString output = args.at(1) + ".patched";
bool replaceOnce = true;
bool replaceAsIs = false;
for (int i = 5, sz = args.size(); i < sz; i++) {
if ((args.at(i) == "-o" || args.at(i) == "--output") && i + 1 < sz) {
output = args.at(i+1);
i++;
} else if (args.at(i) == "-all") {
replaceOnce = false;
} else if (args.at(i) == "-asis") {
replaceAsIs = true;
} else {
result = ERR_INVALID_PARAMETER;
}
}
if (result == ERR_SUCCESS) {
result = r.replace(args.at(1), guid, sectionType, args.at(4), output, replaceAsIs, replaceOnce);
}
}
switch (result) {
case ERR_SUCCESS:
std::cout << "File replaced" << std::endl;
break;
case ERR_INVALID_PARAMETER:
std::cout << "Function called with invalid parameter" << std::endl;
break;
case ERR_INVALID_FILE:
std::cout << "Invalid/corrupted file specified" << std::endl;
break;
case ERR_INVALID_SECTION:
std::cout << "Invalid/corrupted section specified" << std::endl;
break;
case ERR_NOTHING_TO_PATCH:
std::cout << "No replacements can be applied to input file" << std::endl;
break;
case ERR_NOT_IMPLEMENTED:
std::cout << "Can't replace body of this section type" << std::endl;
break;
case ERR_FILE_OPEN:
std::cout << "Input file not found" << std::endl;
break;
case ERR_FILE_READ:
std::cout << "Input file can't be read" << std::endl;
break;
case ERR_FILE_WRITE:
std::cout << "Output file can't be written" << std::endl;
break;
default:
std::cout << "Error " << result << std::endl;
}
return result;
}

View file

@ -16,6 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
typedef uint8_t BOOLEAN;
typedef int8_t INT8;
@ -28,7 +29,7 @@ typedef int64_t INT64;
typedef uint64_t UINT64;
typedef char CHAR8;
typedef uint16_t CHAR16;
typedef unsigned int UINTN;
typedef size_t UINTN;
#define CONST const
#define VOID void
@ -85,6 +86,8 @@ typedef unsigned int UINTN;
#define ERR_INVALID_SYMBOL 40
#define ERR_NOTHING_TO_PATCH 41
#define ERR_DEPEX_PARSE_FAILED 42
#define ERR_TRUNCATED_IMAGE 43
#define ERR_BAD_RELOCATION_ENTRY 44
#define ERR_NOT_IMPLEMENTED 0xFF
// UDK porting definitions

View file

@ -17,11 +17,11 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "basetypes.h"
// Make sure we use right packing rules
#pragma pack(push,1)
#pragma pack(push, 1)
// Flash descriptor header
typedef struct _FLASH_DESCRIPTOR_HEADER {
UINT8 FfVector[16]; // Must be 16 0xFFs
UINT8 FfVector[16]; // Must be 16 0xFFs
UINT32 Signature; // 0x0FF0A55A
} FLASH_DESCRIPTOR_HEADER;
@ -31,40 +31,59 @@ typedef struct _FLASH_DESCRIPTOR_HEADER {
// Descriptor region size
#define FLASH_DESCRIPTOR_SIZE 0x1000
// Descriptor version was reserved in older firmware
#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF
// The only known version found in Coffee Lake
#define FLASH_DESCRIPTOR_VERSION_MAJOR 1
#define FLASH_DESCRIPTOR_VERSION_MINOR 0
// Descriptor version present in Coffee Lake and newer
typedef struct _FLASH_DESCRIPTOR_VERSION {
UINT32 Reserved : 14;
UINT32 Minor : 7;
UINT32 Major : 11;
} FLASH_DESCRIPTOR_VERSION;
// Descriptor map
// Base fields are storing bits [11:4] of actual base addresses, all other bits are 0
typedef struct _FLASH_DESCRIPTOR_MAP {
UINT8 ComponentBase; // 0x03 on most machines
UINT8 NumberOfFlashChips; // Zero-based number of flash chips installed on board
UINT8 RegionBase; // 0x04 on most machines
UINT8 NumberOfRegions; // Zero-based number of flash regions (descriptor is always included)
UINT8 MasterBase; // 0x06 on most machines
UINT8 NumberOfMasters; // Zero-based number of flash masters
UINT8 PchStrapsBase; // 0x10 on most machines
UINT8 NumberOfPchStraps; // One-based number of UINT32s to read as PCH Straps, min=0, max=255 (1 Kb)
UINT8 ProcStrapsBase; // 0x20 on most machines
UINT8 NumberOfProcStraps; // Number of PROC straps to be read, can be 0 or 1
UINT8 IccTableBase; // 0x21 on most machines
UINT8 NumberOfIccTableEntries; // 0x00 on most machines
UINT8 DmiTableBase; // 0x25 on most machines
UINT8 NumberOfDmiTableEntries; // 0x00 on most machines
UINT16 ReservedZero; // Still unknown, zeros in all descriptors I have seen
// FLMAP0
UINT32 ComponentBase : 8;
UINT32 NumberOfFlashChips : 2; // Zero-based number of flash chips installed on board
UINT32 : 6;
UINT32 RegionBase : 8;
UINT32 NumberOfRegions : 3; // Reserved in v2 descriptor
UINT32 : 5;
// FLMAP 1
UINT32 MasterBase : 8;
UINT32 NumberOfMasters : 2; // Zero-based number of flash masters
UINT32 : 6;
UINT32 PchStrapsBase : 8;
UINT32 NumberOfPchStraps : 8; // One-based number of UINT32s to read as PCH straps, min=0, max=255 (1 Kb)
// FLMAP 2
UINT32 ProcStrapsBase : 8;
UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb)
UINT32: 16;
// FLMAP 3
UINT32 DescriptorVersion; // Reserved prior to Coffee Lake
} FLASH_DESCRIPTOR_MAP;
#define FLASH_DESCRIPTOR_MAX_BASE 0xE0
// Component section
// Flash parameters DWORD structure
typedef struct _FLASH_PARAMETERS {
UINT8 FirstChipDensity : 3;
UINT8 SecondChipDensity : 3;
UINT8 ReservedZero0 : 2; // Still unknown, zeros in all descriptors I have seen
UINT8 ReservedZero1 : 8; // Still unknown, zeros in all descriptors I have seen
UINT8 ReservedZero2 : 4; // Still unknown, zeros in all descriptors I have seen
UINT8 FirstChipDensity : 4;
UINT8 SecondChipDensity : 4;
UINT8 : 8;
UINT8 : 1;
UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors and 17 Mhz (110b) in v2 ones
UINT8 FastReadEnabled : 1;
UINT8 FastReadFreqency : 3;
UINT8 FlashReadStatusFrequency : 3;
UINT8 FastReadFrequency : 3;
UINT8 FlashWriteFrequency : 3;
UINT8 FlashReadStatusFrequency : 3;
UINT8 DualOutputFastReadSupported : 1;
UINT8 ReservedZero3 : 1; // Still unknown, zero in all descriptors I have seen
UINT8 : 1;
} FLASH_PARAMETERS;
// Flash densities
@ -74,11 +93,16 @@ typedef struct _FLASH_PARAMETERS {
#define FLASH_DENSITY_4MB 0x03
#define FLASH_DENSITY_8MB 0x04
#define FLASH_DENSITY_16MB 0x05
#define FLASH_DENSITY_32MB 0x06
#define FLASH_DENSITY_64MB 0x07
#define FLASH_DENSITY_UNUSED 0x0F
// Flash frequencies
#define FLASH_FREQUENCY_20MHZ 0x00
#define FLASH_FREQUENCY_33MHZ 0x01
#define FLASH_FREQUENCY_50MHZ 0x04
#define FLASH_FREQUENCY_20MHZ 0x00
#define FLASH_FREQUENCY_33MHZ 0x01
#define FLASH_FREQUENCY_48MHZ 0x02
#define FLASH_FREQUENCY_50MHZ_30MHZ 0x04
#define FLASH_FREQUENCY_17MHZ 0x06
// Component section structure
typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION {
@ -87,52 +111,82 @@ typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION {
UINT8 InvalidInstruction1; //
UINT8 InvalidInstruction2; //
UINT8 InvalidInstruction3; //
UINT16 PartitionBoundary; // Upper 16 bit of partition boundary address. Default is 0x0000, which makes the boundary to be 0x00001000
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
} FLASH_DESCRIPTOR_COMPONENT_SECTION;
// Component section structure
typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION_V2 {
FLASH_PARAMETERS FlashParameters;
UINT8 InvalidInstruction0; // Instructions for SPI chip, that must not be executed, like FLASH ERASE
UINT8 InvalidInstruction1; //
UINT8 InvalidInstruction2; //
UINT8 InvalidInstruction3; //
UINT8 InvalidInstruction4; //
UINT8 InvalidInstruction5; //
UINT8 InvalidInstruction6; //
UINT8 InvalidInstruction7; //
} FLASH_DESCRIPTOR_COMPONENT_SECTION_V2;
// Region section
// All base and limit register are storing upper part of actual UINT32 base and limit
// If limit is zero - region is not present
typedef struct _FLASH_DESCRIPTOR_REGION_SECTION {
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
UINT16 FlashBlockEraseSize; // Size of block erased by single BLOCK ERASE command
UINT16 BiosBase;
UINT16 BiosLimit;
UINT16 MeBase;
UINT16 MeLimit;
UINT16 GbeBase;
UINT16 GbeLimit;
UINT16 PdrBase;
UINT16 PdrLimit;
UINT16 DescriptorBase; // Descriptor
UINT16 DescriptorLimit; //
UINT16 BiosBase; // BIOS
UINT16 BiosLimit; //
UINT16 MeBase; // ME
UINT16 MeLimit; //
UINT16 GbeBase; // GbE
UINT16 GbeLimit; //
UINT16 PdrBase; // PDR
UINT16 PdrLimit; //
UINT16 Region5Base; // Reserved region
UINT16 Region5Limit; //
UINT16 Region6Base; // Reserved region
UINT16 Region6Limit; //
UINT16 Region7Base; // Reserved region
UINT16 Region7Limit; //
UINT16 EcBase; // EC
UINT16 EcLimit; //
} FLASH_DESCRIPTOR_REGION_SECTION;
// Flash block erase sizes
#define FLASH_BLOCK_ERASE_SIZE_4KB 0x0000
#define FLASH_BLOCK_ERASE_SIZE_8KB 0x0001
#define FLASH_BLOCK_ERASE_SIZE_64KB 0x000F
// Master section
typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION {
UINT16 BiosId;
UINT8 BiosRead;
UINT8 BiosWrite;
UINT8 BiosRead;
UINT8 BiosWrite;
UINT16 MeId;
UINT8 MeRead;
UINT8 MeWrite;
UINT8 MeRead;
UINT8 MeWrite;
UINT16 GbeId;
UINT8 GbeRead;
UINT8 GbeWrite;
UINT8 GbeRead;
UINT8 GbeWrite;
} FLASH_DESCRIPTOR_MASTER_SECTION;
// Master section v2 (Skylake+)
typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION_V2 {
UINT32 : 8;
UINT32 BiosRead : 12;
UINT32 BiosWrite : 12;
UINT32 : 8;
UINT32 MeRead : 12;
UINT32 MeWrite : 12;
UINT32 : 8;
UINT32 GbeRead : 12;
UINT32 GbeWrite : 12;
UINT32 :32;
UINT32 : 8;
UINT32 EcRead : 12;
UINT32 EcWrite : 12;
} FLASH_DESCRIPTOR_MASTER_SECTION_V2;
// Region access bits in master section
#define FLASH_DESCRIPTOR_REGION_ACCESS_DESC 0x01
#define FLASH_DESCRIPTOR_REGION_ACCESS_BIOS 0x02
#define FLASH_DESCRIPTOR_REGION_ACCESS_ME 0x04
#define FLASH_DESCRIPTOR_REGION_ACCESS_GBE 0x08
#define FLASH_DESCRIPTOR_REGION_ACCESS_PDR 0x10
//!TODO: Describe PCH and PROC straps sections, as well as ICC and DMI tables
#define FLASH_DESCRIPTOR_REGION_ACCESS_EC 0x20
// Base address of descriptor upper map
#define FLASH_DESCRIPTOR_UPPER_MAP_BASE 0x0EFC
@ -155,7 +209,7 @@ typedef struct _VSCC_TABLE_ENTRY {
// Base address and size of OEM section
#define FLASH_DESCRIPTOR_OEM_SECTION_BASE 0x0F00
#define FLASH_DESCRIPTOR_OEM_SECTION_SIZE 0xFF
#define FLASH_DESCRIPTOR_OEM_SECTION_SIZE 0x100
// Restore previous packing rules
#pragma pack(pop)

21
ffs.cpp
View file

@ -30,7 +30,10 @@ const QVector<QByteArray> FFSv3Volumes =
const UINT8 ffsAlignmentTable[] =
{ 0, 4, 7, 9, 10, 12, 15, 16 };
UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
const UINT8 ffsAlignment2Table[] =
{ 17, 18, 19, 20, 21, 22, 23, 24 };
UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize)
{
if (!buffer)
return 0;
@ -40,7 +43,15 @@ UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
while (bufferSize--)
counter += buffer[bufferSize];
return (UINT8)0x100 - counter;
return counter;
}
UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
{
if (!buffer)
return 0;
return (UINT8)0x100 - calculateSum8(buffer, bufferSize);
}
UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize)
@ -120,6 +131,8 @@ QString fileTypeToQString(const UINT8 type)
case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return QObject::tr("Volume image");
case EFI_FV_FILETYPE_COMBINED_SMM_DXE: return QObject::tr("Combined SMM/DXE");
case EFI_FV_FILETYPE_SMM_CORE: return QObject::tr("SMM core");
case EFI_FV_FILETYPE_SMM_STANDALONE: return QObject::tr("SMM standalone");
case EFI_FV_FILETYPE_SMM_CORE_STANDALONE: return QObject::tr("SMM core standalone");
case EFI_FV_FILETYPE_PAD: return QObject::tr("Pad");
default: return QObject::tr("Unknown");
};
@ -156,9 +169,9 @@ UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header)
return 0;
bool extended = false;
/*if (uint24ToUint32(header->Size) == EFI_SECTION2_IS_USED) {
if (uint24ToUint32(header->Size) == EFI_SECTION2_IS_USED) {
extended = true;
}*/
}
switch (header->Type)
{

45
ffs.h
View file

@ -32,7 +32,7 @@ extern QString sectionTypeToQString(const UINT8 type);
//*****************************************************************************
// EFI Capsule
//*****************************************************************************
// Capsule header
// Standard EFI Capsule header
typedef struct _EFI_CAPSULE_HEADER {
EFI_GUID CapsuleGuid;
UINT32 HeaderSize;
@ -49,16 +49,32 @@ typedef struct _EFI_CAPSULE_HEADER {
const QByteArray EFI_CAPSULE_GUID
("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16);
// Intel capsule GUID
const QByteArray INTEL_CAPSULE_GUID
("\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC", 16);
// Toshiba EFI Capsule header
typedef struct _TOSHIBA_CAPSULE_HEADER {
EFI_GUID CapsuleGuid;
UINT32 HeaderSize;
UINT32 FullSize;
UINT32 Flags;
} TOSHIBA_CAPSULE_HEADER;
// Toshiba capsule GUID
const QByteArray TOSHIBA_CAPSULE_GUID
("\x62\x70\xE0\x3B\x51\x1D\xD2\x45\x83\x2B\xF0\x93\x25\x7E\xD4\x61", 16);
// AMI Aptio extended capsule header
typedef struct _APTIO_CAPSULE_HEADER {
EFI_CAPSULE_HEADER CapsuleHeader;
UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of
UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of
// the capsule volume
//!TODO: Enable certificate and ROM layout reading
//UINT16 RomLayoutOffset; // offset to the table of the module descriptors in the capsule's volume
//UINT16 RomLayoutOffset; // offset to the table of the module descriptors in the capsule's volume
// that are included in the signature calculation
//FW_CERTIFICATE FWCert;
//ROM_AREA RomAreaMap[1];
//ROM_AREA RomAreaMap[1];
} APTIO_CAPSULE_HEADER;
// AMI Aptio signed extended capsule GUID
@ -93,7 +109,7 @@ typedef struct _EFI_FIRMWARE_VOLUME_HEADER {
UINT16 ExtHeaderOffset; //Reserved in Revision 1
UINT8 Reserved;
UINT8 Revision;
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1];
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2];
} EFI_FIRMWARE_VOLUME_HEADER;
// Standard file system GUIDs
@ -252,8 +268,8 @@ extern UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize);
// Integrity check
typedef union {
struct {
UINT8 Header;
UINT8 File;
UINT8 Header;
UINT8 File;
} Checksum;
UINT16 TailReference; // Revision 1
UINT16 Checksum16; // Revision 2
@ -276,7 +292,7 @@ UINT8 Type;
UINT8 Attributes;
UINT8 Size[3]; // Set to 0xFFFFFF
UINT8 State;
UINT32 ExtendedSize;
UINT64 ExtendedSize;
} EFI_FFS_FILE_HEADER2;
// Standard data checksum, used if FFS_ATTRIB_CHECKSUM is clear
@ -298,6 +314,8 @@ UINT32 ExtendedSize;
#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B
#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C
#define EFI_FV_FILETYPE_SMM_CORE 0x0D
#define EFI_FV_FILETYPE_SMM_STANDALONE 0x0E
#define EFI_FV_FILETYPE_SMM_CORE_STANDALONE 0x0F
#define EFI_FV_FILETYPE_OEM_MIN 0xC0
#define EFI_FV_FILETYPE_OEM_MAX 0xDF
#define EFI_FV_FILETYPE_DEBUG_MIN 0xE0
@ -310,6 +328,7 @@ UINT32 ExtendedSize;
#define FFS_ATTRIB_TAIL_PRESENT 0x01 // Valid only for revision 1 volumes
#define FFS_ATTRIB_RECOVERY 0x02 // Valid only for revision 1 volumes
#define FFS_ATTRIB_LARGE_FILE 0x01 // Valid only for FFSv3 volumes
#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02 // Valid only for revision 2 volumes
#define FFS_ATTRIB_FIXED 0x04
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
#define FFS_ATTRIB_CHECKSUM 0x40
@ -317,6 +336,9 @@ UINT32 ExtendedSize;
// FFS alignment table
extern const UINT8 ffsAlignmentTable[];
// Extended FFS alignment table
extern const UINT8 ffsAlignment2Table[];
// File states
#define EFI_FILE_HEADER_CONSTRUCTION 0x01
#define EFI_FILE_HEADER_VALID 0x02
@ -324,6 +346,7 @@ extern const UINT8 ffsAlignmentTable[];
#define EFI_FILE_MARKED_FOR_UPDATE 0x08
#define EFI_FILE_DELETED 0x10
#define EFI_FILE_HEADER_INVALID 0x20
#define EFI_FILE_ERASE_POLARITY 0x80 // Defined as "all other bits must be set to ERASE_POLARITY" in UEFI PI
// PEI apriori file
const QByteArray EFI_PEI_APRIORI_FILE_GUID
@ -344,7 +367,9 @@ const QByteArray EFI_FFS_PAD_FILE_GUID
// FFS size conversion routines
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
extern UINT32 uint24ToUint32(const UINT8* ffsSize);
// FFS file 8bit checksum calculation routine
// FFS file 8bit checksum calculation routines
extern UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize);
extern UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize);
//*****************************************************************************
@ -512,7 +537,7 @@ typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
//Section routines
// Section routines
extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
//*****************************************************************************

File diff suppressed because it is too large Load diff

View file

@ -67,22 +67,23 @@ public:
UINT8 parseMeRegion(const QByteArray & me, QModelIndex & index, const QModelIndex & parent, const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseBiosRegion(const QByteArray & bios, QModelIndex & index, const QModelIndex & parent, const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parsePdrRegion(const QByteArray & pdr, QModelIndex & index, const QModelIndex & parent, const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseEcRegion(const QByteArray & ec, QModelIndex & index, const QModelIndex & parent, const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseBios(const QByteArray & bios, const QModelIndex & parent = QModelIndex());
UINT8 parseVolume(const QByteArray & volume, QModelIndex & index, const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseFile(const QByteArray & file, QModelIndex & index, const UINT8 erasePolarity = ERASE_POLARITY_UNKNOWN, const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseFile(const QByteArray & file, QModelIndex & index, const UINT8 revision = 2, const UINT8 erasePolarity = ERASE_POLARITY_UNKNOWN, const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
UINT8 parseSections(const QByteArray & body, const QModelIndex & parent = QModelIndex());
UINT8 parseSection(const QByteArray & section, QModelIndex & index, const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
// Compression routines
UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedData, UINT8 * algorithm = NULL);
UINT8 compress(const QByteArray & data, const UINT8 algorithm, QByteArray & compressedData);
UINT8 compress(const QByteArray & data, const UINT8 algorithm, const UINT32 dictionarySize, QByteArray & compressedData);
// Construction routines
UINT8 reconstructImageFile(QByteArray &reconstructed);
UINT8 reconstruct(const QModelIndex &index, QByteArray & reconstructed);
UINT8 reconstructIntelImage(const QModelIndex& index, QByteArray & reconstructed);
UINT8 reconstructRegion(const QModelIndex& index, QByteArray & reconstructed);
UINT8 reconstructBios(const QModelIndex& index, QByteArray & reconstructed);
UINT8 reconstructRegion(const QModelIndex& index, QByteArray & reconstructed, bool includeHeader = true);
UINT8 reconstructPadding(const QModelIndex& index, QByteArray & reconstructed);
UINT8 reconstructVolume(const QModelIndex& index, QByteArray & reconstructed);
UINT8 reconstructFile(const QModelIndex& index, const UINT8 revision, const UINT8 erasePolarity, const UINT32 base, QByteArray& reconstructed);
UINT8 reconstructSection(const QModelIndex& index, const UINT32 base, QByteArray & reconstructed);
@ -94,6 +95,7 @@ public:
UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode);
UINT8 remove(const QModelIndex & index);
UINT8 rebuild(const QModelIndex & index);
UINT8 doNotRebuild(const QModelIndex & index);
UINT8 dump(const QModelIndex & index, const QString & path, const QString & filter = QString());
UINT8 patch(const QModelIndex & index, const QVector<PatchData> & patches);
@ -115,7 +117,6 @@ private:
UINT8 parseDepexSection(const QByteArray & body, QString & parsed);
UINT8 findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
UINT8 getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
UINT8 getFileSize(const QByteArray & volume, const UINT32 fileOffset, UINT32 & fileSize);
UINT8 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, UINT32 & sectionSize);
// Reconstruction helpers
@ -125,7 +126,7 @@ private:
// Rebase routines
UINT8 getBase(const QByteArray& file, UINT32& base);
UINT8 getEntryPoint(const QByteArray& file, UINT32 &entryPoint);
UINT8 rebase(QByteArray & executable, const UINT32 base);
UINT8 rebase(QByteArray & executable, const UINT32 base, const QModelIndex & index);
void rebasePeiFiles(const QModelIndex & index);
// Patch routines

View file

@ -17,18 +17,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, const UINT8 compression,
const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
const QByteArray & header, const QByteArray & body,
TreeItem *parent) :
itemAction(Actions::NoAction),
itemType(type),
itemSubtype(subtype),
itemCompression(compression),
itemDictionarySize(0),
itemName(name),
itemText(text),
itemInfo(info),
itemHeader(header),
itemBody(body),
itemParsingData(parsingData),
parentItem(parent)
{
}
@ -184,11 +184,6 @@ QByteArray TreeItem::body() const
return itemBody;
}
QByteArray TreeItem::parsingData() const
{
return itemParsingData;
}
bool TreeItem::hasEmptyHeader() const
{
return itemHeader.isEmpty();
@ -199,21 +194,21 @@ bool TreeItem::hasEmptyBody() const
return itemBody.isEmpty();
}
bool TreeItem::hasEmptyParsingData() const
{
return itemParsingData.isEmpty();
}
void TreeItem::setParsingData(const QByteArray & data)
{
itemParsingData = data;
}
UINT8 TreeItem::action() const
{
return itemAction;
}
UINT32 TreeItem::dictionarySize() const
{
return itemDictionarySize;
}
void TreeItem::setDictionarySize(const UINT32 dictionarySize)
{
itemDictionarySize = dictionarySize;
}
void TreeItem::setAction(const UINT8 action)
{
itemAction = action;
@ -228,4 +223,3 @@ void TreeItem::setAction(const UINT8 action)
&& parentItem->action() == Actions::NoAction)
parentItem->setAction(Actions::Rebuild);
}

View file

@ -26,7 +26,7 @@ class TreeItem
public:
TreeItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
TreeItem *parent = 0);
~TreeItem();
@ -63,10 +63,6 @@ public:
QByteArray body() const;
bool hasEmptyBody() const;
QByteArray parsingData() const;
bool hasEmptyParsingData() const;
void setParsingData(const QByteArray & data);
QString info() const;
void addInfo(const QString &info);
void setInfo(const QString &info);
@ -76,18 +72,21 @@ public:
UINT8 compression() const;
UINT32 dictionarySize() const;
void setDictionarySize(const UINT32 dictionarySize);
private:
QList<TreeItem*> childItems;
UINT8 itemAction;
UINT8 itemType;
UINT8 itemSubtype;
UINT8 itemCompression;
UINT32 itemDictionarySize;
QString itemName;
QString itemText;
QString itemInfo;
QByteArray itemHeader;
QByteArray itemBody;
QByteArray itemParsingData;
TreeItem *parentItem;
};

View file

@ -178,22 +178,6 @@ bool TreeModel::hasEmptyBody(const QModelIndex &index) const
return item->hasEmptyBody();
}
QByteArray TreeModel::parsingData(const QModelIndex &index) const
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->parsingData();
}
bool TreeModel::hasEmptyParsingData(const QModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyParsingData();
}
QString TreeModel::name(const QModelIndex &index) const
{
if (!index.isValid())
@ -234,6 +218,14 @@ UINT8 TreeModel::compression(const QModelIndex &index) const
return item->compression();
}
UINT32 TreeModel::dictionarySize(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->dictionarySize();
}
void TreeModel::setSubtype(const QModelIndex & index, const UINT8 subtype)
{
if (!index.isValid())
@ -284,20 +276,19 @@ void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
emit dataChanged(this->index(0, 0), index);
}
void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
void TreeModel::setDictionarySize(const QModelIndex &index, const UINT32 dictionarySize)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setParsingData(data);
item->setDictionarySize(dictionarySize);
emit dataChanged(this->index(0, 0), index);
}
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT8 compression,
const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
const QModelIndex & parent, const UINT8 mode)
const QByteArray & header, const QByteArray & body, const QModelIndex & parent, const UINT8 mode)
{
TreeItem *item = 0;
TreeItem *parentItem = 0;
@ -318,7 +309,7 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT
}
}
TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, parsingData, parentItem);
TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, parentItem);
if (mode == CREATE_MODE_APPEND) {
emit layoutAboutToBeChanged();
parentItem->appendChild(newItem);

View file

@ -47,7 +47,7 @@ public:
void setSubtype(const QModelIndex &index, const UINT8 subtype);
void setName(const QModelIndex &index, const QString &name);
void setText(const QModelIndex &index, const QString &text);
void setParsingData(const QModelIndex &index, const QByteArray &data);
void setDictionarySize(const QModelIndex &index, const UINT32 dictionarySize);
QString name(const QModelIndex &index) const;
QString text(const QModelIndex &index) const;
@ -58,14 +58,13 @@ public:
bool hasEmptyHeader(const QModelIndex &index) const;
QByteArray body(const QModelIndex &index) const;
bool hasEmptyBody(const QModelIndex &index) const;
QByteArray parsingData(const QModelIndex &index) const;
bool hasEmptyParsingData(const QModelIndex &index) const;
UINT8 action(const QModelIndex &index) const;
UINT8 compression(const QModelIndex &index) const;
UINT32 dictionarySize(const QModelIndex &index) const;
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;

View file

@ -24,11 +24,13 @@ QString regionTypeToQString(const UINT8 type)
case Subtypes::GbeRegion:
return QObject::tr("GbE");
case Subtypes::MeRegion:
return QObject::tr("ME/TXE");
return QObject::tr("ME");
case Subtypes::BiosRegion:
return QObject::tr("BIOS");
case Subtypes::PdrRegion:
return QObject::tr("PDR");
case Subtypes::EcRegion:
return QObject::tr("EC");
default:
return QObject::tr("Unknown");
};
@ -67,7 +69,7 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
case Types::Image:
if (subtype == Subtypes::IntelImage)
return QObject::tr("Intel");
else if (Subtypes::UefiImage)
else if (subtype == Subtypes::UefiImage)
return QObject::tr("UEFI");
else
return QObject::tr("Unknown subtype");
@ -80,7 +82,7 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
return QObject::tr("Non-empty");
else
return QObject::tr("Unknown subtype");
case Types::Volume:
case Types::Volume:
if (subtype == Subtypes::UnknownVolume)
return QObject::tr("Unknown");
else if (subtype == Subtypes::Ffs2Volume)
@ -89,14 +91,16 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
return QObject::tr("FFSv3");
else
return QObject::tr("Unknown subtype");
case Types::Capsule:
case Types::Capsule:
if (subtype == Subtypes::AptioSignedCapsule)
return QObject::tr("Aptio signed");
else if (subtype == Subtypes::AptioUnsignedCapsule)
return QObject::tr("Aptio unsigned");
else if (subtype == Subtypes::UefiCapsule)
return QObject::tr("UEFI 2.0 ");
else
return QObject::tr("UEFI 2.0");
else if (subtype == Subtypes::ToshibaCapsule)
return QObject::tr("Toshiba");
else
return QObject::tr("Unknown subtype");
case Types::Region:
return regionTypeToQString(subtype);
@ -146,7 +150,9 @@ QString actionTypeToQString(const UINT8 action)
return QObject::tr("Rebuild");
case Actions::Rebase:
return QObject::tr("Rebase");
case Actions::DoNotRebuild:
return QObject::tr("Do not rebuild");
default:
return QObject::tr("Unknown");
}
}
}

30
types.h
View file

@ -26,7 +26,8 @@ namespace Actions
Replace,
Remove,
Rebuild,
Rebase
Rebase,
DoNotRebuild
};
}
@ -54,7 +55,8 @@ namespace Subtypes {
enum CapsuleSubtypes {
AptioSignedCapsule = 80,
AptioUnsignedCapsule,
UefiCapsule
UefiCapsule,
ToshibaCapsule
};
enum VolumeSubtypes {
@ -68,7 +70,8 @@ namespace Subtypes {
GbeRegion,
MeRegion,
BiosRegion,
PdrRegion
PdrRegion,
EcRegion
};
enum PaddingSubtypes {
@ -85,25 +88,4 @@ extern QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype);
extern QString compressionTypeToQString(const UINT8 algorithm);
extern QString regionTypeToQString(const UINT8 type);
enum ParsingDataTypes {
UnknownParsingData,
VolumeParsingData,
FileParsingData
};
typedef union _PARSING_DATA_UNION {
struct _PARSING_DATA_UNION_VOLUME {
bool HasZeroVectorCRC;
} Volume;
struct _PARSING_DATA_UNION_FILE {
UINT32 Offset;
} File;
} PARSING_DATA_UNION;
typedef struct _PARSING_DATA {
UINT8 Type;
PARSING_DATA_UNION Data;
} PARSING_DATA;
#endif

View file

@ -11,13 +11,14 @@
*/
#include "version.h"
#include "uefitool.h"
#include "ui_uefitool.h"
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
version(tr("0.20.4"))
ui(new Ui::UEFITool),
version(tr(PROGRAM_VERSION))
{
clipboard = QApplication::clipboard();
@ -31,6 +32,7 @@ version(tr("0.20.4"))
// Connect signals to slots
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
connect(ui->actionOpenImageFileInNewWindow, SIGNAL(triggered()), this, SLOT(openImageFileInNewWindow()));
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
connect(ui->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs()));
@ -42,6 +44,7 @@ version(tr("0.20.4"))
connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody()));
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
connect(ui->actionDoNotRebuild, SIGNAL(triggered()), this, SLOT(doNotRebuild()));
connect(ui->actionMessagesCopy, SIGNAL(triggered()), this, SLOT(copyMessage()));
connect(ui->actionMessagesCopyAll, SIGNAL(triggered()), this, SLOT(copyAllMessages()));
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
@ -83,6 +86,11 @@ UEFITool::~UEFITool()
delete searchDialog;
}
void UEFITool::setProgramPath(QString path)
{
currentProgramPath = path;
};
void UEFITool::init()
{
// Clear components
@ -140,6 +148,7 @@ void UEFITool::populateUi(const QModelIndex &current)
// Enable actions
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionDoNotRebuild->setEnabled(type== Types::Region || type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
@ -147,7 +156,7 @@ void UEFITool::populateUi(const QModelIndex &current)
(type == Types::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE)));
ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section);
ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section);
ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Padding || type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionReplaceBody->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionMessagesCopy->setEnabled(false);
}
@ -214,6 +223,18 @@ void UEFITool::rebuild()
ui->actionSaveImageFile->setEnabled(true);
}
void UEFITool::doNotRebuild()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
UINT8 result = ffsEngine->doNotRebuild(index);
if (result == ERR_SUCCESS)
ui->actionSaveImageFile->setEnabled(true);
}
void UEFITool::remove()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
@ -321,6 +342,13 @@ void UEFITool::replace(const UINT8 mode)
else
return;
}
else if (model->type(index) == Types::Padding) {
if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select padding file to replace selected object"), currentDir, "Padding files (*.pad *.bin);;All files (*)");
}
else
return;
}
else if (model->type(index) == Types::Volume) {
if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected object"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
@ -358,6 +386,8 @@ void UEFITool::replace(const UINT8 mode)
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC)
path = QFileDialog::getOpenFileName(this, tr("Select EFI executable file to replace body"), currentDir, "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)");
else
path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"), currentDir, "Binary files (*.bin);;All files (*)");
}
@ -447,7 +477,7 @@ void UEFITool::extract(const UINT8 mode)
case Types::Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), currentDir, "Image files (*.rom *.bin);;All files (*)");
break;
case Types::Volume:
case Types::Volume:
path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
break;
case Types::File: {
@ -521,7 +551,7 @@ void UEFITool::exit()
void UEFITool::saveImageFile()
{
QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi *.dec);;All files (*)");
QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.dec);;All files (*)");
if (path.isEmpty())
return;
@ -552,10 +582,18 @@ void UEFITool::saveImageFile()
void UEFITool::openImageFile()
{
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi *.dec);;All files (*)");
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.dec);;All files (*)");
openImageFile(path);
}
void UEFITool::openImageFileInNewWindow()
{
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.dec);;All files (*)");
if (path.trimmed().isEmpty())
return;
QProcess::startDetached(currentProgramPath, QStringList(path));
}
void UEFITool::openImageFile(QString path)
{
if (path.trimmed().isEmpty())

View file

@ -27,6 +27,7 @@
#include <QMessageBox>
#include <QMimeData>
#include <QPlainTextEdit>
#include <QProcess>
#include <QSettings>
#include <QSplitter>
#include <QString>
@ -51,6 +52,7 @@ public:
~UEFITool();
void openImageFile(QString path);
void setProgramPath(QString path);
private slots:
void init();
@ -58,6 +60,7 @@ public:
void scrollTreeView(QListWidgetItem* item);
void openImageFile();
void openImageFileInNewWindow();
void saveImageFile();
void search();
@ -75,6 +78,7 @@ public:
void replaceBody();
void rebuild();
void doNotRebuild();
void remove();
@ -95,6 +99,7 @@ private:
SearchDialog* searchDialog;
QClipboard* clipboard;
QString currentDir;
QString currentProgramPath;
QQueue<MessageListItem> messageItems;
const QString version;

View file

@ -39,6 +39,7 @@ HEADERS += uefitool.h \
treemodel.h \
messagelistitem.h \
guidlineedit.h \
version.h \
LZMA/LzmaCompress.h \
LZMA/LzmaDecompress.h \
Tiano/EfiTianoDecompress.h \

View file

@ -180,7 +180,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
<height>31</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -188,6 +188,7 @@
<string>&amp;File</string>
</property>
<addaction name="actionOpenImageFile"/>
<addaction name="actionOpenImageFileInNewWindow"/>
<addaction name="actionSaveImageFile"/>
<addaction name="separator"/>
<addaction name="actionSearch"/>
@ -224,6 +225,8 @@
</property>
<addaction name="actionExtract"/>
<addaction name="separator"/>
<addaction name="actionDoNotRebuild"/>
<addaction name="separator"/>
<addaction name="actionReplace"/>
</widget>
<widget class="QMenu" name="menuPaddingActions">
@ -231,6 +234,8 @@
<string>&amp;Padding</string>
</property>
<addaction name="actionExtract"/>
<addaction name="separator"/>
<addaction name="actionReplace"/>
</widget>
<widget class="QMenu" name="menuVolumeActions">
<property name="title">
@ -240,6 +245,7 @@
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="actionDoNotRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="separator"/>
@ -254,6 +260,7 @@
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="actionDoNotRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="actionInsertBefore"/>
@ -272,6 +279,7 @@
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="actionDoNotRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="actionInsertBefore"/>
@ -281,7 +289,6 @@
<addaction name="actionReplaceBody"/>
<addaction name="separator"/>
<addaction name="actionRemove"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuMessages">
<property name="title">
@ -522,6 +529,28 @@
<string>Ctrl+Alt+C</string>
</property>
</action>
<action name="actionOpenImageFileInNewWindow">
<property name="text">
<string>&amp;Open image file in new window...</string>
</property>
<property name="toolTip">
<string>Open image file in new window</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+O</string>
</property>
</action>
<action name="actionDoNotRebuild">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Do not rebuild</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+Space</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>

View file

@ -23,6 +23,7 @@ int main(int argc, char *argv[])
a.setApplicationName("UEFITool");
UEFITool w;
w.setProgramPath(a.arguments().at(0));
if (a.arguments().length() > 1)
w.openImageFile(a.arguments().at(1));
w.show();

118
unixbuild.sh Executable file
View file

@ -0,0 +1,118 @@
#!/bin/bash
UTARGET=$(uname)
BINSUFFIX=""
if [ "$UTARGET" = "Darwin" ]; then
export UPLATFORM="mac"
elif [ "$UTARGET" = "Linux" ]; then
export UPLATFORM="linux_$(uname -m)"
elif [ "${UTARGET/MINGW32/}" != "$UTARGET" ]; then
export UPLATFORM="win32"
export BINSUFFIX=".exe"
else
# Fallback to something...
export UPLATFORM="$UTARGET"
fi
if [ "$UPLATFORM" = "mac" ]; then
if [ ! -d /opt/qt56sm ]; then
curl -L -o /tmp/qt-5.6.3-static-mac.zip https://github.com/distdb/qtbuilds/blob/master/qt-5.6.3-static-mac.zip?raw=true || exit 1
qtsum=$(shasum -a 256 /tmp/qt-5.6.3-static-mac.zip | cut -f1 -d' ')
qtexpsum="214d22d8572ea6162753c8dd251d79275f3b22d49204718c637d722409e0cfcb"
if [ "$qtsum" != "$qtexpsum" ]; then
echo "Qt hash $qtsum does not match $qtexpsum"
exit 1
fi
sudo mkdir -p /opt || exit 1
cd /opt || exit 1
sudo unzip -q /tmp/qt-5.6.3-static-mac.zip || exit 1
cd - || exit 1
fi
export PATH="/opt/qt56sm/bin:$PATH"
elif [ "$UPLATFORM" = "win32" ]; then
# Install missing dependencies
pacman -S --noconfirm --needed zip unzip curl perl mingw-w64-i686-toolchain mingw-w64-i686-cmake || exit 1
# Fix PATH to support running shasum.
export PATH="/usr/bin/core_perl:$PATH"
if [ ! -d "/c/Qt/5.6/mingw49_32_release_static/" ]; then
curl -L -o /tmp/qt-5.6.3-static-win32.zip https://github.com/distdb/qtbuilds/blob/master/qt-5.6.3-static-win32.zip?raw=true || exit 1
qtsum=$(shasum -a 256 /tmp/qt-5.6.3-static-win32.zip | cut -f1 -d' ')
qtexpsum="bcd85145d6fed00da37498c08c49d763c6fa883337f754880b5c786899e6bb1d"
if [ "$qtsum" != "$qtexpsum" ]; then
echo "Qt hash $qtsum does not match $qtexpsum"
exit 1
fi
mkdir -p /c/Qt/5.6 || exit 1
cd /c/Qt/5.6 || exit 1
unzip -q /tmp/qt-5.6.3-static-win32.zip || exit 1
cd - || exit 1
fi
export PATH="/c/Qt/5.6/mingw49_32_release_static/bin:$PATH"
fi
echo "Attempting to build UEFITool for ${UPLATFORM}..."
UEFITOOL_VER=$(cat version.h | grep PROGRAM_VERSION | cut -d'"' -f2)
build_tool() {
echo "Building $1 $2"
# Check version
if [ "$(echo "$2" | grep '^[0-9]*\.[0-9]*\.[0-9]*$')" != "$2" ]; then
echo "Invalid $1 version!"
exit 1
fi
# Tools are in subdirectories
if [ "$1" != "UEFITool" ]; then
cd "$1" || exit 1
fi
# Build
# -flto is flawed on CI atm
if [ "$UPLATFORM" = "mac" ]; then
qmake $3 QMAKE_CXXFLAGS+=-flto QMAKE_LFLAGS+=-flto CONFIG+=optimize_size || exit 1
elif [ "$UPLATFORM" = "win32" ]; then
qmake $3 QMAKE_CXXFLAGS="-static -flto -Os" QMAKE_LFLAGS="-static -flto -Os" CONFIG+=optimize_size CONFIG+=staticlib CONFIG+=static || exit 1
else
qmake $3 CONFIG+=optimize_size || exit 1
fi
make || exit 1
# Move the binary out of the dir
if [ "$UPLATFORM" = "win32" ]; then
mv "release/${1}${BINSUFFIX}" "${1}${BINSUFFIX}" || exit 1
fi
# Archive
if [ "$1" = "UEFITool" ]; then
if [ "$UPLATFORM" = "mac" ]; then
strip -x UEFITool.app/Contents/MacOS/UEFITool || exit 1
zip -qry dist/"${1}_${2}_${UPLATFORM}.zip" UEFITool.app ${4} || exit 1
else
strip -x "${1}${BINSUFFIX}" || exit 1
zip -qry dist/"${1}_${2}_${UPLATFORM}.zip" "${1}${BINSUFFIX}" ${4} || exit 1
fi
else
strip -x "${1}${BINSUFFIX}" || exit 1
zip -qry ../dist/"${1}_${2}_${UPLATFORM}.zip" "${1}${BINSUFFIX}" ${4} || exit 1
fi
# Return to parent
if [ "$1" != "UEFITool" ]; then
cd - || exit 1
fi
}
rm -rf dist
mkdir -p dist || exit 1
build_tool UEFITool "$UEFITOOL_VER" uefitool.pro
build_tool UEFIPatch "$UEFITOOL_VER" uefipatch.pro patches*.txt
build_tool UEFIReplace "$UEFITOOL_VER" uefireplace.pro
exit 0

19
version.h Normal file
View file

@ -0,0 +1,19 @@
/* types.h
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef VERSION_H
#define VERSION_H
#define PROGRAM_VERSION "0.26.0"
#endif // VERSION_H