Giter Club home page Giter Club logo

bmc-tools's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bmc-tools's Issues

Decode issue

HI nitrogenc ,
I'm new in Python, so maybe I doing something wrong.
When I run the script the decode error appears.
I think that something is going wrong with utf-8 encoding...
Please help me solve this issue.
I appreciate you help in advance.

C:\Python34>python C:\Python34\bmc-tools.py -s "C:\input" -d "C:\output" -v
Traceback (most recent call last):
File "C:\Python34\bmc-tools.py", line 7, in
class BMCContainer():
File "C:\Python34\bmc-tools.py", line 14, in BMCContainer
PALETTE = "00000000000080000080000000808000800000008000800080800000C0C0C000C0DCC000F0CAA60000204
00000206000002080000020A0000020C0000020E00000400000004020000040400000406000004080000040A0000040C0000
040E00000600000006020000060400000606000006080000060A0000060C0000060E00000800000008020000080400000806
000008080000080A0000080C0000080E00000A0000000A0200000A0400000A0600000A0800000A0A00000A0C00000A0E0000
0C0000000C0200000C0400000C0600000C0800000C0A00000C0C00000C0E00000E0000000E0200000E0400000E0600000E08
00000E0A00000E0C00000E0E00040000000400020004000400040006000400080004000A0004000C0004000E000402000004
02020004020400040206000402080004020A0004020C0004020E00040400000404020004040400040406000404080004040A
0004040C0004040E00040600000406020004060400040606000406080004060A0004060C0004060E00040800000408020004
080400040806000408080004080A0004080C0004080E00040A0000040A0200040A0400040A0600040A0800040A0A00040A0C
00040A0E00040C0000040C0200040C0400040C0600040C0800040C0A00040C0C00040C0E00040E0000040E0200040E040004
0E0600040E0800040E0A00040E0C00040E0E00080000000800020008000400080006000800080008000A0008000C0008000E
00080200000802020008020400080206000802080008020A0008020C0008020E000804000008040200080404000804060008
04080008040A0008040C0008040E00080600000806020008060400080606000806080008060A0008060C0008060E00080800
000808020008080400080806000808080008080A0008080C0008080E00080A0000080A0200080A0400080A0600080A080008
0A0A00080A0C00080A0E00080C0000080C0200080C0400080C0600080C0800080C0A00080C0C00080C0E00080E0000080E02
00080E0400080E0600080E0800080E0A00080E0C00080E0E000C0000000C0002000C0004000C0006000C0008000C000A000C
000C000C000E000C0200000C0202000C0204000C0206000C0208000C020A000C020C000C020E000C0400000C0402000C0404
000C0406000C0408000C040A000C040C000C040E000C0600000C0602000C0604000C0606000C0608000C060A000C060C000C
060E000C0800000C0802000C0804000C0806000C0808000C080A000C080C000C080E000C0A00000C0A02000C0A04000C0A06
000C0A08000C0A0A000C0A0C000C0A0E000C0C00000C0C02000C0C04000C0C06000C0C08000C0C0A000F0FBFF00A4A0A0008
08080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00".decode("hex")
AttributeError: 'str' object has no attribute 'decode'

Extracted BMP files can't be opened

Source: Windows Server 2012 R2
bcache*.bmc = 0 Byte
cache????.bin = 104,9 MB

python bmc-tools.py -d /opt/output/ -s /opt/input/ --> not working
python bmc-tools.py -d /opt/output/ -s /opt/input/ -v --> works

6400 files successfully extracted. All files are 17 KB and can't be opened.

I can't extract RDP cache

Hi ,
I can't extract RDP cache file

python3 bmc-tools.py -s E:\naw -d E:\out
i got this message
Invalid -s/--src parameter; use -h/--help for help.

also I try this command

python3 ./bmc-tools.py -s E:\naw -d E:\out

Having an issue with compressed bitmaps

I'm new to this tool, and I was testing it RDP from Server 2008 -> server 2003. This is the output:

`C:\Users\Administrator>python bmc-tools.py -d extracted -s "C:\Users\Administrat
or\AppData\Local\Microsoft\Terminal Server Client\Cache" -v
[+++] Processing a directory...
[---] File 'C:\Users\Administrator\AppData\Local\Microsoft\Terminal Server Clien
t\Cache\bcache22.bmc' has been found.
[===] Successfully loaded 'C:\Users\Administrator\AppData\Local\Microsoft\Termin
al Server Client\Cache\bcache22.bmc' as a .BMC container.
[!!!] Tile data is compressed (5632 bytes compressed in 25 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1107 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1276 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 879 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 227 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 128 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 1149 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 365 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 1358 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 170 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 101 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 26 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 809 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 127 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 145 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 128 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 752 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 122 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 98 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 24 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (4864 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 433 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 513 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 85 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 288 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 263 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 25 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 27 bytes); skipping.
[!!!] Tile data is compressed (4864 bytes compressed in 25 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1162 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1233 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 21 bytes); skipping.
[!!!] Tile data is compressed (15616 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (4352 bytes compressed in 120 bytes); skipping.
[!!!] Tile data is compressed (4352 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (4352 bytes compressed in 21 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 25 bytes); skipping.
[!!!] Tile data is compressed (15616 bytes compressed in 25 bytes); skipping.
[!!!] Tile data is compressed (7680 bytes compressed in 124 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 1130 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 363 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 138 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1505 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1722 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 642 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 852 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 42 bytes); skipping.
[!!!] Tile data is compressed (5120 bytes compressed in 138 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 788 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 130 bytes); skipping.
[!!!] Tile data is compressed (5632 bytes compressed in 44 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1752 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 1369 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 27 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 459 bytes); skipping.
[!!!] Tile data is compressed (16384 bytes compressed in 284 bytes); skipping.
[!!!] Tile data is compressed (4864 bytes compressed in 23 bytes); skipping.
[!!!] Tile data is compressed (4864 bytes compressed in 27 bytes); skipping.
[===] 0 tiles successfully extracted in the end.
[===] Successfully exported 0 files.

C:\Users\Administrator>
`

Is it not possible to extract compressed data?

Bug with extracted bitmap size

Hello!!

First of all, thank you so much for this. I've recommended this to just about everyone who has dealt with RDP Bitmap Cache data, because I have not found anything that processes it nearly as well, fast, or reliable as your script.

As I am working on enhancing my script to automate the rebuilding/pattern matching of the pieces, I came across a bug in your code, with regards to the bitmap header file size. The code understates the size of the outputted bitmap images by a total of four bytes. I think this is because the original math did not account for the "BM" header, plus the two byte file length.

So, lines 201-203 are currently

return "BM"+pack("<L", len(data)+126)+"\x00\x00\x00\x00\x7A\x00\x00\x00\x6C\x00\x00\x00"+pack("<L", width)+pack("<L", height)+"\x01\x00\x20\x00\x03\x00\x00\x00"+pack("<L", len(data))+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\xFF niW"+("\x00"*36)+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+data else: return "BM"+pack("<L", len(data)+0x36)+"\x00\x00\x00\x00\x36\x04\x00\x00\x28\x00\x00\x00"+pack("<L", width)+pack("<L", height)+"\x01\x00\x08\x00\x00\x00\x00\x00"+pack("<L", len(data)-0x400)+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+data

and it should be

return "BM"+pack("<L", len(data)+122)+"\x00\x00\x00\x00\x7A\x00\x00\x00\x6C\x00\x00\x00"+pack("<L", width)+pack("<L", height)+"\x01\x00\x20\x00\x03\x00\x00\x00"+pack("<L", len(data))+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\xFF niW"+("\x00"*36)+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+data else: return "BM"+pack("<L", len(data)+0x32)+"\x00\x00\x00\x00\x36\x04\x00\x00\x28\x00\x00\x00"+pack("<L", width)+pack("<L", height)+"\x01\x00\x08\x00\x00\x00\x00\x00"+pack("<L", len(data)-0x400)+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+data

Really all that has to be changed is the value of "126" and "0x36" to "122" and "0x32" respectively.

Thank you again, and I hope that helps!

Brian

Few Error handling Items for Bitmap Collage and Zero-Byte files.

Adding Exceptions for bitmap collage if not enough files are present with default -WIDTH of 64

            try:
                c_bmp = b"" if not self.pal else self.PALETTE
                if self.btype == self.BIN_CONTAINER:
                    collage_builder = (lambda x, a=self, PAD=len(pad), WIDTH=list(range(w // 64)): b''.join([b''.join([a.bmps[a.STRIPE_WIDTH*(x+1)-1-k][64*PAD*j:64*PAD*(j+1)] for k in WIDTH]) for j in range(64)]))
                else:
                    collage_builder = (lambda x, a=self, PAD=len(pad), WIDTH=list(range(w // 64)): b''.join([b''.join([a.bmps[a.STRIPE_WIDTH*x+k][64*PAD*j:64*PAD*(j+1)] for k in WIDTH]) for j in range(64)]))
                c_bmp += b''.join(map(collage_builder, list(range(h//64))))
                self.b_write(os.path.join(dname, "%s_collage.bmp" % (self.fname)), self.b_export_bmp(w, h, c_bmp))
                self.b_log(sys.stdout, False, 0, "Successfully exported collage file.")
            except IndexError as ie:
                self.b_log(sys.stdout, False, 1, "Not enough files to build collage with default collage -WIDTH of 64")
               
            try:
                c_bmp = b"" if not self.pal else self.PALETTE
                if self.btype == self.BIN_CONTAINER:
                    collage_builder = (lambda x, a=self, PAD=len(pad), WIDTH=list(range(w // 64)): b''.join([b''.join([a.bmps[a.STRIPE_WIDTH*(x+1)-1-k][64*PAD*j:64*PAD*(j+1)] for k in WIDTH]) for j in range(64)]))
                else:
                    collage_builder = (lambda x, a=self, PAD=len(pad), WIDTH=list(range(w // 64)): b''.join([b''.join([a.bmps[a.STRIPE_WIDTH*x+k][64*PAD*j:64*PAD*(j+1)] for k in WIDTH]) for j in range(64)]))
                c_bmp += b''.join(map(collage_builder, list(range(h//64))))
                self.b_write(os.path.join(dname, "%s_collage.bmp" % (self.fname)), self.b_export_bmp(w, h, c_bmp))
                self.b_log(sys.stdout, False, 0, "Successfully exported collage file.")
            except IndexError as ie:
                self.b_log(sys.stdout, False, 1, "Not enough files to build collage with default collage -WIDTH of 64")

Add in an exception and skip for zero byte files in Argparse Options:

    # Process all files in a directory
    elif os.path.isdir(args.src):
        sys.stdout.write("[+++] Processing a directory...%s" % (os.linesep))
        src_files = []
        for root, dirs, files in os.walk(args.src):
            for f in files:
                if f.rsplit(".", 1)[-1].upper() in ["BIN", "BMC"]:
                    file_path = os.path.join(root, f)
                    file_size = os.path.getsize(file_path)
                    if file_size > 0:
                        if args.verbose:
                            sys.stdout.write("[---] File '%s' has been found.%s" % (file_path, os.linesep))
                        src_files.append(os.path.join(root, f))
                    else:
                        sys.stdout.write("[!!!] File '%s' is zero bytes, skipping file.%s" % (file_path, os.linesep))
        if len(src_files) == 0:
            sys.stderr.write("No suitable files were found under '%s' directory.%s" % (args.src, os.linesep))
            exit(-1)

    # Process a single file
    elif not os.path.isfile(args.src):
        sys.stderr.write("Invalid -s/--src parameter; use -h/--help for help.%s" % (os.linesep))
        exit(-1)
    else:
        file_size = os.path.getsize(args.src)
        if file_size > 0:
            sys.stdout.write("[+++] Processing a single file: '%s'.%s" % (args.src, os.linesep))
            src_files = [args.src]
        else:
            sys.stdout.write("[!!!] File '%s' is Zero-Bytes.%s" % (args.src, os.linesep))
    # Import, process, export, and flush each file
    print("[+++] Files for processing:", str(src_files))

Port to js

HI, thanks for the cool tool.
It would be nice to be able to run the tool in browser.
This way it could be integrated to CyberChef or run in custom .html solutions.

I see two solutions for this request:

  1. Rewrite to .js
  2. Run using "pyodide"

I would prefer the first solution, but I also checked the pyodide. It should be easy to run it in the web python with slight modifications.

CacheXXXX.bin from W2K8 R2 SP1 / invalid version number.

Hi

Running your script on a cacheXX.bin extracted from a W2K8 R2 SP1, it crashed with a div/0
File "bmc-tools.py", line 68, in b_process
cf = t_len/(t_width*t_height)
ZeroDivisionError: long division or modulo by zero

Looking at the code, it's just that the header is not detected as a bin file but a bmc :

C:\temp>hexdump Cache0000.bin
00000000: 52 44 50 38 62 6D 70 00 - 04 00 00 00 95 E6 95 F9 |RDP8bmp |
But you check if the file starts with "RDP8bmp\x00\x03\x00\x00\x00" to detect it as a bin file...

Modifying the \x03 with \x04 is enough to parse and extract the tiles from the cache file. Anyway, you've done a great tool guyz !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.