How can I identify the way data is being iterated through in a Wireshark capture?

I’m trying to reverse engineer the screen on the Epomaker RT100 keyboard, specifically the image uploading component. I used Wireshark to track the packets sent over USB. I found that RGB 565 is being used to send data and there are two 8-bit values that seem to count pixels. The issue is I can’t figure out how the data is being iterated through. It doesn’t seem to be simple rows or columns.

I have gotten to a point where things show up, however they are garbled. When comparing the packets from the code I wrote to the packets from the included software they are different.

The image shows the packets when uploading this image:

The one on the left is from the software the one on the right is mine. How could I find out how this is sending the data to the image.

And just for clarity, this is the code I wrote:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>from PIL import Image
import struct
import usb.util
import usb.core
import time
def convert_rgb888_to_rgb565(rgb):
r, g, b, a = rgb
r = (r >> 3) & 0x1F
g = (g >> 2) & 0x3F
b = (b >> 3) & 0x1F
return (r << 11) | (g << 5) | b
def encode_image_to_rgb565(image_path):
img = Image.open(image_path)
img = img.rotate(0)
pixels = list(img.getdata())
encoded_data = []
for pixel in pixels:
encoded = convert_rgb888_to_rgb565(pixel)
encoded_data.append(struct.pack('!H', encoded))
return b''.join(encoded_data)
encoded_image = encode_image_to_rgb565('rainbow.png')
screen = usb.core.find(idVendor=0x3151, idProduct=0x4015) #This is the actual screen, not the hub
if screen is None:
raise ValueError('Device not found')
# Send initial control transfer
screen.set_configuration(1)
initial_payload = bytes.fromhex("a5000100f4da008b0000a2ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, initial_payload)
screen.ctrl_transfer(0xA1, 0x01, 0x0300, 2, 64) #GET_REPORT
# Header data = 25 00 01 00 __ 00 38 __
# 0 161 wwww3w
y = 0x00
x = 0xA1
# Split and send data in chunks
chunk_size = 56 # Use 56 bytes for chunk to leave room for the 8-byte header
for i in range(0, len(encoded_image), chunk_size):
header = [0x25, 0x00, 0x01, 0x00, y, 0x00, 0x38, x]
chunk = encoded_image[i:(i + chunk_size)]
# Combine header and chunk
combined = bytes(header) + chunk
# Ensure combined is exactly 64 bytes
if len(combined) < 64:
combined += b'x00' * (64 - len(combined)) # Pad with zeros
#Print the combined packet
print(f'Header: {header}')
print(f'Chunk: {chunk.hex()}')
print(f'Combined: {combined.hex()}')
if x - 1 > -1:
x = int(x) - 1
else:
x = 255
if y + 1 < 256:
y = int(y) + 1
else:
y = 0
print(combined)
screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, combined)
print("Image uploaded.")
usb.util.dispose_resources(screen)
</code>
<code>from PIL import Image import struct import usb.util import usb.core import time def convert_rgb888_to_rgb565(rgb): r, g, b, a = rgb r = (r >> 3) & 0x1F g = (g >> 2) & 0x3F b = (b >> 3) & 0x1F return (r << 11) | (g << 5) | b def encode_image_to_rgb565(image_path): img = Image.open(image_path) img = img.rotate(0) pixels = list(img.getdata()) encoded_data = [] for pixel in pixels: encoded = convert_rgb888_to_rgb565(pixel) encoded_data.append(struct.pack('!H', encoded)) return b''.join(encoded_data) encoded_image = encode_image_to_rgb565('rainbow.png') screen = usb.core.find(idVendor=0x3151, idProduct=0x4015) #This is the actual screen, not the hub if screen is None: raise ValueError('Device not found') # Send initial control transfer screen.set_configuration(1) initial_payload = bytes.fromhex("a5000100f4da008b0000a2ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, initial_payload) screen.ctrl_transfer(0xA1, 0x01, 0x0300, 2, 64) #GET_REPORT # Header data = 25 00 01 00 __ 00 38 __ # 0 161 wwww3w y = 0x00 x = 0xA1 # Split and send data in chunks chunk_size = 56 # Use 56 bytes for chunk to leave room for the 8-byte header for i in range(0, len(encoded_image), chunk_size): header = [0x25, 0x00, 0x01, 0x00, y, 0x00, 0x38, x] chunk = encoded_image[i:(i + chunk_size)] # Combine header and chunk combined = bytes(header) + chunk # Ensure combined is exactly 64 bytes if len(combined) < 64: combined += b'x00' * (64 - len(combined)) # Pad with zeros #Print the combined packet print(f'Header: {header}') print(f'Chunk: {chunk.hex()}') print(f'Combined: {combined.hex()}') if x - 1 > -1: x = int(x) - 1 else: x = 255 if y + 1 < 256: y = int(y) + 1 else: y = 0 print(combined) screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, combined) print("Image uploaded.") usb.util.dispose_resources(screen) </code>
from PIL import Image
import struct
import usb.util
import usb.core
import time

def convert_rgb888_to_rgb565(rgb):
    r, g, b, a = rgb
    r = (r >> 3) & 0x1F
    g = (g >> 2) & 0x3F
    b = (b >> 3) & 0x1F
    return (r << 11) | (g << 5) | b

def encode_image_to_rgb565(image_path):
    img = Image.open(image_path)
    img = img.rotate(0)
    pixels = list(img.getdata())
    encoded_data = []
    for pixel in pixels:
        encoded = convert_rgb888_to_rgb565(pixel)
        encoded_data.append(struct.pack('!H', encoded))
    return b''.join(encoded_data)

encoded_image = encode_image_to_rgb565('rainbow.png')

screen = usb.core.find(idVendor=0x3151, idProduct=0x4015) #This is the actual screen, not the hub

if screen is None:
    raise ValueError('Device not found')


# Send initial control transfer
screen.set_configuration(1)
initial_payload = bytes.fromhex("a5000100f4da008b0000a2ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, initial_payload)


screen.ctrl_transfer(0xA1, 0x01, 0x0300, 2, 64) #GET_REPORT

# Header data = 25 00 01 00 __ 00 38 __
#                          0       161   wwww3w

y = 0x00
x = 0xA1

# Split and send data in chunks
chunk_size = 56  # Use 56 bytes for chunk to leave room for the 8-byte header
for i in range(0, len(encoded_image), chunk_size):
    header = [0x25, 0x00, 0x01, 0x00, y, 0x00, 0x38, x]
    chunk = encoded_image[i:(i + chunk_size)]

    # Combine header and chunk
    combined = bytes(header) + chunk

    # Ensure combined is exactly 64 bytes
    if len(combined) < 64:
        combined += b'x00' * (64 - len(combined))  # Pad with zeros

    #Print the combined packet
    print(f'Header: {header}')
    print(f'Chunk: {chunk.hex()}')
    print(f'Combined: {combined.hex()}')

    if x - 1 > -1:
        x = int(x) - 1
    else:
        x = 255
    if y + 1 < 256:
        y = int(y) + 1
    else:
        y = 0


    print(combined)
    screen.ctrl_transfer(0x21, 0x09, 0x0300, 2, combined)

print("Image uploaded.")

usb.util.dispose_resources(screen)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật