virtualbox .sav 파일에서 정보를 추출 중이신가요?

virtualbox .sav 파일에서 정보를 추출 중이신가요?

.sav복원하고 싶은 VirtualBox 파일이 있습니다 . 하지만 문제는 이 파일만 가지고 있다는 것입니다(디스크 파일 및 RAM 크기 등에 대한 다른 정보는 없음). 내 가상 머신 중 하나를 복제하려고 시도하고 스냅샷을 만들고 스냅샷을 교체했습니다(올바른 파일 이름으로). 상태를 복원할 때 VirtualBox에서 오류가 발생했습니다.

'mm' 단위를 로드하지 못했습니다(VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH).

메모리 크기를 모르기 때문에 계속 진행할 수 없습니다.

인터넷 검색 후 스냅샷 파일에 가상 머신의 모든 정보와 구성이 포함되어 있음을 발견했습니다. .sav올바른 구성을 얻을 수 있도록 파일 에서 정보를 추출할 수 있는 방법이 있습니까 ?

답변1

다음은 이 글을 쓰는 시점의 VirtualBox 최신 버전(4.3)에 관한 것입니다. 이전 버전에 대해서는 말할 수 없습니다.

파일 SAVunits. SAV16진수 편집기에서 파일을 열면 다음 16진수 문자열을 검색하여 단위를 탐색할 수 있습니다.

0A 55 6E 69 74 0A 00 00

Unit이것은 주변에 다른 문자가 있는 단어입니다 . 적중 후 0x24(36)바이트가 지나면 일부 ASCII 문자가 표시됩니다. 예를 들어 첫 번째 항목은 아마도 다음과 같습니다 SSM. 이는 단위에 대한 설명자이며, 이 경우에는 'Saved State Manager'입니다.

(Memory Manager) 장치 를 찾고 싶습니다 mm. 나에게는 항상 SAV 파일의 세 번째 단위였습니다. 따라서 검색 시 세 번째 결과는 다음과 같습니다.

16진수:

0A 55 6E 69 74 0A 00 00 52 01 00 00 00 00 00 00 7C 36 11 91 CE B0 E2
CE 02 00 00 00 01 00 00 00 FF FF FF FF 00 00 00 00 03 00 00 00 6D 6D
00 92 10 1E 00 08 00 00 00 00 00 00 00 00 80 00 00 00 00 91 0E 01 00
38 7E D4 06 22 00 00 00 00 00 00 00

보시다시피 처음 8바이트가 unit헤더입니다. 그런 다음 0x24(36)바이트 6D 6D 00후에 mm\0. 3바이트를 건너뛰면( 92 10 1E) 스냅샷이 생성된 당시의 시스템 메모리 양인 uint16(리틀 엔디안)이 생성됩니다. 내 예에서는 00 08= 0x800= 2048= 2GB.

답변2

당신은vboxmanage 채택 상태, 문서에 따르면 현재 스냅샷을 제안된 저장 상태에 연결하기 위해 VM을 변경하려고 시도합니다.

작동하지 않는 경우 parsiya는 여기에서 찾을 수 있는 SAV 상태 구문 분석에 대한 흥미로운 블로그를 작성했습니다.파시야 블로그

그의 블로그에 따르면 SAVE 상태는 다음과 같습니다.SSM.cpp

내가 찾은 새로운 정보는 SSMFILEHDRV12(parsiya보다 최신)를 기반으로 합니다. RTGCPHYS의 단위는 GIM_HV_PAGE_SIZE(4096)입니다. 내가 올바르게 이해했다면 그것은 더 많은 단위이며 일반적으로 08 * 4096입니다. 실제로 추가로 생성된 데이터에 대한 또 다른 단위가 있습니다.

처음에 설명한 SSM.cpp 코드의 논리를 올바르게 이해했다면 라이브 저장 상태를 수행하는 것입니다. 즉 전체 크기를 알 수 없습니다. 따라서 여러 단위의 메모리가 기록될 수 있습니다. 원시 메모리 단위가 하나만 있는 경우에는 VM 크기를 추론할 수 있습니다. 마일리지는 다양함

파일의 시작 부분에서 추출

 * The live snapshots feature (LS) is similar to teleportation (TP) and was a
 * natural first step when implementing TP.  The main differences between LS and
 * TP are that after a live snapshot we will have a saved state file, disk image
 * snapshots, and the VM will still be running.
 *  * Compared to normal saved stated and snapshots, the difference is in that the
 * VM is running while we do most of the saving.  Prior to LS, there was only
 * one round of callbacks during saving and the VM was paused during it.  With
 * LS there are 1 or more passes while the VM is still running and a final one
 * after it has been paused.  The runtime passes are executed on a dedicated
 * thread running at at the same priority as the EMTs so that the saving doesn't
 * starve or lose in scheduling questions (note: not implemented yet). The final
 * pass is done on EMT(0).

 * The saved state units each starts with a variable sized header
 * (SSMFILEUNITHDRV2) that contains the name, instance and pass.  The data
 * follows the header and is encoded as records with a 2-8 byte record header
 * indicating the type, flags and size.  The first byte in the record header
 * indicates the type and flags:
 *  *   - bits 0..3: Record type:
 *       - type 0: Invalid.
 *       - type 1: Terminator with CRC-32 and unit size.
 *       - type 2: Raw data record.
 *       - type 3: Raw data compressed by LZF. The data is prefixed by a 8-bit
 *                 field containing the length of the uncompressed data given in
 *                 1KB units.
 *       - type 4: Zero data. The record header is followed by a 8-bit field
 *                 counting the length of the zero data given in 1KB units.
 *       - type 5: Named data - length prefixed name followed by the data. This
 *                 type is not implemented yet as we're missing the API part, so
 *                 the type assignment is tentative.
 *       - types 6 thru 15 are current undefined.
 *   - bit 4: Important (set), can be skipped (clear).
 *   - bit 5: Undefined flag, must be zero.
 *   - bit 6: Undefined flag, must be zero.
 *   - bit 7: "magic" bit, always set.  
 /**
 * Writes a record header for the specified amount of data.
 *
 * @returns VBox status code. Sets pSSM->rc on failure.
 * @param   pSSM            The saved state handle
 * @param   cb              The amount of data.
 * @param   u8TypeAndFlags  The record type and flags.
 */
static int ssmR3DataWriteRecHdr(PSSMHANDLE pSSM, size_t cb, uint8_t u8TypeAndFlags)
{
    size_t  cbHdr;
    uint8_t abHdr[8];
    abHdr[0] = u8TypeAndFlags;
    if (cb < 0x80)
    {
        cbHdr = 2;
        abHdr[1] = (uint8_t)cb;
    }
    else if (cb < 0x00000800)
    {
        cbHdr = 3;
        abHdr[1] = (uint8_t)(0xc0 | (cb >> 6));
        abHdr[2] = (uint8_t)(0x80 | (cb & 0x3f));
    }
    else if (cb < 0x00010000)
    {
        cbHdr = 4;
        abHdr[1] = (uint8_t)(0xe0 | (cb >> 12));
        abHdr[2] = (uint8_t)(0x80 | ((cb >> 6) & 0x3f));
        abHdr[3] = (uint8_t)(0x80 | (cb & 0x3f));
    }
    else if (cb < 0x00200000)
    {
        cbHdr = 5;
        abHdr[1] = (uint8_t)(0xf0 |  (cb >> 18));
        abHdr[2] = (uint8_t)(0x80 | ((cb >> 12) & 0x3f));
        abHdr[3] = (uint8_t)(0x80 | ((cb >>  6) & 0x3f));
        abHdr[4] = (uint8_t)(0x80 |  (cb        & 0x3f));
    }
    else if (cb < 0x04000000)
    {
        cbHdr = 6;
        abHdr[1] = (uint8_t)(0xf8 |  (cb >> 24));
        abHdr[2] = (uint8_t)(0x80 | ((cb >> 18) & 0x3f));
        abHdr[3] = (uint8_t)(0x80 | ((cb >> 12) & 0x3f));
        abHdr[4] = (uint8_t)(0x80 | ((cb >>  6) & 0x3f));
        abHdr[5] = (uint8_t)(0x80 |  (cb        & 0x3f));
    }
    else if (cb <= 0x7fffffff)
    {
        cbHdr = 7;
        abHdr[1] = (uint8_t)(0xfc |  (cb >> 30));
        abHdr[2] = (uint8_t)(0x80 | ((cb >> 24) & 0x3f));
        abHdr[3] = (uint8_t)(0x80 | ((cb >> 18) & 0x3f));
        abHdr[4] = (uint8_t)(0x80 | ((cb >> 12) & 0x3f));
        abHdr[5] = (uint8_t)(0x80 | ((cb >>  6) & 0x3f));
        abHdr[6] = (uint8_t)(0x80 | (cb & 0x3f));
    }
    else
        AssertLogRelMsgFailedReturn(("cb=%#x\n", cb), pSSM->rc = VERR_SSM_MEM_TOO_BIG);

    Log3(("ssmR3DataWriteRecHdr: %08llx|%08llx/%08x: Type=%02x fImportant=%RTbool cbHdr=%u\n",
          ssmR3StrmTell(&pSSM->Strm) + cbHdr, pSSM->offUnit + cbHdr, cb, u8TypeAndFlags & SSM_REC_TYPE_MASK, !!(u8TypeAndFlags & SSM_REC_FLAGS_IMPORTANT), cbHdr));

    return ssmR3DataWriteRaw(pSSM, &abHdr[0], cbHdr);
}

그는 또한 Bridgey처럼 단위가 ASCII "Unit"으로 시작하지만 마지막 단위가 "TheEnd"로 끝나는 것을 발견했습니다.

그는 SSMInternal.h에 설명된 UNIT의 구조를 기반으로 SAV 파일의 일부 구조를 구문 분석했습니다.Virtualbox 오픈소스 헤더

관련 정보