|
Convincing Real Player Plus G2 to Record
Enabling Record Functionality for Audio Clips
|
Not Assigned
|
20 May 1999
| by
sNw
|
|
|
Courtesy of Fravia's page of
reverse engineering
|
slightly edited
by fravia+
|
fra_00xx 990521 sNw 1100 NA PC
|
Amazing essay! A very deep reversing study. Once more we demonstate that NOTHING can held us. sNw wanted
to "analyze the various dialects and patterns of speech" for reasons of "linguistic reversing". And what
does he do when he discovers that there are no right
tools for doing this? He modifies, fiddles and creates them.
Note also how important is what sNw writes: "it is one thing to have the tools and quite another thing to
possess a clear enough train of thought to use the right ones effectively". How true! Our strength is
in our heads! In
order to reverse
software reversers
should sit more in the shadows of a nice garden than before their screen... :-)
There are some lessons for protectors as well in here, note in particular what sNw says about SDK
documentation... Moreover "Real Player Plus G2" programmers will be able -if they want-
not only to better protect, but also to improve decisively their own software after having read this great essay.
| |
|
There is a crack, a crack in everything
That's how the light gets in
| |
Rating
|
(X)Beginner (X)Intermediate ( )Advanced ( )Expert
| |
This essay was written for the benefit of beginners but may spark some ideas
for more advanced reversers as well.
Convincing Real Player Plus G2 to Record
Enabling Record Functionality for Audio Clips
Written by
sNw
For reasons of linguistic reversing, my goal was to use some audio utility to save clips
of various world broadcasts so that I could analyze the various dialects and patterns of
speech. I felt that RealPlayer Plus G2 was the best tool for this goal and I was willing
to pay the registration fee to have a good utility which would record online streaming
clips.
Unfortunately, I discovered that very few, if any, radio stations designate their clips
as "recordable", so for my purposes, the registeration appeared worthless. I soon
realized that x86 had reversed RealPlayer 4.0 to add the recording functionality to every
clip (see his 2 wonderful essays: x86new1.htm and x86dd2.htm). While a lot has changed
with RealPlayer and x86's modifications no longer work, they gave me the idea of reversing
the new RealPlayer. As a lot of functionality was added to RealPlayer Plus G2, I felt the
benefits of reversing it would be well worth the effort.
Before I outline the direct method I succeeded with, I would like to mention that I spent
many nights spinning my wheels with faulty plans such as using BoundsChecker, Spy++, and
other message-related utils for this project. I wasted yet another night fiddling with
resource editors and trapping for windows events. Finally, after many exhausted evenings,
I decided to step back from the problem and take a break for a while. A week later, my mind
was clear and focused and within 2 hours, I had completely solved my problem in a logical
fashion. I say this because it is one thing to have the tools and quite another thing to
possess a clear enough train of thought to use the right ones effectively. Sometimes you
just need to step back for a while and clear the mind.
SoftIce 3.21
W32Dasm 8.9
WinGrep (http://kili.pncl.co.uk/~huw/grep/index.html) or other pattern searching utility.
any hex editor
Real Producer G2 (optional) It can be found at www.real.com
Patience (ha!)
I'm sure Real Player Plus G2 is downloadable somewhere. (I registered so they mailed me the
program.) Otherwise, download the demo Real Player G2 from http://www.real.com and read
+TsehP's essay on creating a keygen for it.
Before beginning any reversing project, one should study the related works of peers. I
read x86's essays many times, and would suggest the same of the reader. Also, check out
what kind of support you can gain from the target itself or its company by reading the
help files, searching web sites, etc. In my experience, this kind of information
background will provide the crucial clues to an application's behavior at a critical
point in the reversing process. By checking RealPlayer's website, I was able to download
and study a SDK which explained in detail the file/stream formats, methods, etc. This
information, while not absolutely needed, did provide a basis for a clear plan of attack.
If you will agree that at some point in time, a "recordable flag" in the form of a byte or
series of bytes must be read from the incoming file or stream and processed by the
RealPlayer application before any determination of "recordable" or not can be determined,
then we have all the basis we need to get started. The goal is to isolate this flag check
and convince RealPlayer that any given clip is "recordable", whether designated that way or
not. Loosely stated, our plan will be to breakpoint at the point where the flag is initially
"read", and trace through the code (using breakpoints) until we locate the place where this
flag is checked by the application.
Although we really want to find the flag check for streaming audio clips, it will be much
easier to find it for local files for several reasons. Using local files allows us to work
at our leisure without worries of ISP timeouts and such as well as providing us with a nice
initial breakpoint (bpx ReadFile). Once we have solved the recording issue for local files
(functionally useless as one could just copy the file, eh?!), we will then work toward the
real goal of enabling recording for streaming clips.
We can either use RealProducer G2 to create two identical files, with the single exception
that one is "recordable" and the other is not and compare the files to locate the
"recordable" flag byte(s), or we can read the SDK and learn that the recordable flag byte is
located at the end of the "Properties" (designated by 'PROP') header. Hopefully, you will
do both! The advantage of the first method is that by fiddling with the data, you will
discover that the byte difference is only 1. So, by taking any non-recordable file, you can
make it recordable by simply incrementing this flag byte by 1. Noting the value of this
flag byte will help sound off bells in your mind as you see it float into various registers
during the debugging process.
That said, let's use FileMon to discover which "reads" access this flag byte, and
referencing the Win32 API, we can figure out the memory buffer for these reads and set
breakpoints on the flag byte just after it is read in memory. (The alternative is to search
memory for the header information and set breakpoints accordingly, but this technique is
less robust and may lead to mental errors if one is not careful.) Whenever it is accessed,
we will know and by tracing further we will eventually hit the flag check.
Here is a sample of FileMon's output (while playing a local .rm file with RealPlayer) with
comments added:
0 Open SUCCESS OPENEXISTING READONLY DENYWRITE
1 Read SUCCESS Offset: 0 Length: 8192 ;Read 1st 8192 bytes (headers + more)
2 Seek SUCCESS Beginning Offset: 0
3 Close SUCCESS CLOSE_FINAL
4 Open SUCCESS OPENEXISTING READONLY DENYWRITE
5 Read SUCCESS Offset: 0 Length: 8 ;RM Header{ObjID & Size_Of_RM_Header}
6 Seek SUCCESS Beginning Offset: 0
7 Read SUCCESS Offset: 0 Length: 8 ;RM Header{ObjID & Size_Of_RM_Header}
8 Read SUCCESS Offset: 8 Length: 10 ;Rest of RM Hdr{ObjVer, FileVer,NumHdrs}
9 Seek SUCCESS Beginning Offset: 0
10 Read SUCCESS Offset: 0 Length: 8 ;RM Header{ObjID & Size_Of_RM_Header}
11 Seek SUCCESS Beginning Offset: 18
12 Read SUCCESS Offset: 18 Length: 8 ;Prop Header{ObjID & Size_Of_PropHdr}
13 Read SUCCESS Offset: 26 Length: 42 ;Rest of Prop Hdr{ObjVer, Max_bit_rate,
Avg_bit_rate, max_pckt_size, avg_pckt_size,
Num_interleave, Duration(milliseconds),
Preroll(milliseconds), indx_offset,
ata_offset, num_streams, ***flag byte***}
Actually, there are many more reads, but only two of them (#1 & #13 above) read in the flag
byte. Depending upon the structure of the file (each file has several "headers", but they
may be in a different order), your FileMon output may be different. Again, reading the SDK
and examining the local .rm files being played will make many things clear!
The ReadFile API function is as follows:
BOOL ReadFile(HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // pointer to buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
LPOVERLAPPED lpOverlapped); // pointer to structure for data
Simply setting "bpx ReadFile" and playing the local file again will automatically pop
SoftIce at the first target read. Note the memory offset of the lpBuffer (do a
"d *(ss:esp+8)" and jot down the address, remembering to account for the backwards-
looking way the number appears in memory.) In looking at the memory buffer, it should be
easy to spot the flag byte. Set a breakpoint on this memory location (bpm ds:offset rw).
Repeat the same method for the other target read. (To get there quickly, you could change
"bpx ReadFile" to "bpx ReadFile if *(ss:esp+C)==2C" or something similar. Otherwise, just
skip the intermediate reads.)
Once the appropriate "bpm" is set for this read, you can disable the ReadFile breakpoint and
whenever SoftIce pops on the memory breakpoints, follow the code a little to see what is
happening. If the flag byte is copied elsewhere in memory, set a breakpoint there as well.
Eventually, you are sure to find this code in PNEN3260.DLL:
(There is nothing magic to finding this code, just noticing interesting things such as
2Ch = 44d = offset of flag byte within Properties header, might pique your curiosity. When
suspicious, always examine the register values, memory values, etc. A "d esp+2C" here would
have revealed the flag byte value you noted earlier. Actually, the "and ???, 1" caught my
eye.)
:62108F04 8B4C242C mov ecx, dword ptr[esp+2C] ;Move flag byte into ecx
:62108F08 83E101 and ecx, 1 ;Mask for bit 1 (recordable bit)
The trick here is knowing that within the flag byte, bit 1 is the recordable bit. You will
know this if you have read the documentation or x86's essays, as this important information
is clearly outlined. If you are currently playing a non-recordable clip, change ecx value
to 1 by "r ecx=1", disable all breakpoints, and continue execution to discover that you can
now record. Terrific! It is now time to solve the problem for streaming clips.
If you check out the deadlisting of PNEN3260.DLL, and look at the code instructions
surrounding offset 62108F04 (the above lines of code), you will discover a string reference to
"Flags". According to the documentation, the header values are stored in memory with
associated tags, so it makes sense that our flag byte would be saved with the tag, "Flags".
Not only does this reaffirm our success in locating the flag check, it may also lead us to the
final goal of finding the flag check for the streaming clips. From reading x86's essays and
knowing a little of the history of RealPlayer, we can reasonably assume that the flag check for
streaming clips will also be found in PNEN3260.DLL. The next logical step is to search the
deadlisting for other occurrences of "Flags". Sure enough, this yields another location, very
similar to the code we found above. However, if you set a "bpx" on this code offset, SoftIce
will never pop as it appears this code is not being used. Well, at least Zen-wise, I think we
are on the right track. Rather than set a series of breakpoints (where would you start,
anyway?) and spend hours online debugging, let's think about the success we've already had and
see if we can apply this knowledge to finding the solution in the deadlisting.
Since we know that multiple flag values exist in a single byte and that the "and" instruction
has *already* been used in the previous flag check, then now is the time to pull out a file
search utility (IMO, better for sifting through a large number of lines than the old "Find"-
"Find Next" method.) and search the deadlisting for lines with "and ???, 00000001". (BTW, I
feel that a file searching utility, such as WinGrep, can be used to much advantage in searching
for patterns in a directory of PE dumps, binary files, etc. For example, if we had the idea
to search all RealPlayer executables and DLLs for "Flags", then we would have immediately
found our first flag check in less than a minute. Don't underestimate the power of this
technique!)
Anyway, the "and" search returns about a dozen lines. Our plan will be to "bpx" on each of
these offsets, and then play a streaming clip with RealPlayer, hoping for a SoftIce pop or two
which may lead to the flag check we are seeking. Since our live debugging will now be involving
live data streams from the Internet, taking too much time in SoftIce will time out our connection.
Rather than type each of these breakpoints in "on the fly" and risk typo errors or timeouts, why
not take your time and add them to a hotkey via the WinIce.Dat file. I added the following lines
to my file (3 lines, 4 breakpoints to a line) and rebooted:
CF3="bpx cs:...; bpx cs:...;...;"
CF4="bpx cs:...; bpx cs:...;...;", etc.
Then I set a breakpoint such as "bpx ReadFile" and played a clip. When SoftIce popped, I got rid
of my "bpx Readfile" or whatever, and quickly pressed Ctrl-F3, Ctrl-F4, and Ctrl-F5 to set my 12
breakpoints.
Once you have set these breakpoints and continued execution, you will find that SoftIce only pops
for 3 or 4 of the breakpoints, and of these, only two appear to "make sense". (It doesn't "make
sense" if the same breakpoint pops several times in the loading or playing of a single clip.) To
save yourself some aggravation, disable all other breakpoints. Re-play the streaming clip, and
check each of the two breakpoints (one per run!) by forcing the "and" condition to return a 1
(use "r edx=1", or whatever is necessary). One of these breakpoints will cause your machine to crash
and die (just kidding). Seriously, one of these breakpoints will work! For me, it was
"bpx cs:62123BFB". The corresponding code in the deadlisting is:
:62123BF8 8A5030 mov dl, byte ptr[eax+30] ;Move flag byte (or recordable byte) into dl
:62123BFB 83E201 and edx, 1 ;Recordable? (1=yes, 0=no)
So, if we change "mov dl, byte ptr[eax+30]" to "mov dl, 1", our problem will be solved. Hex edit
PNEN3260.DLL, search for "8A503083" and replace with "B2019083" to patch Real Player Plus G2.
(For those who are not sure how to figure out "B201" = "mov dl, 1", set a "bpx ReadFile" or other
breakpoint and play another clip. When SoftIce pops, F12 until you see a bunch of "nop" lines
after a function return. Use "a cs:nop-offset" to add some code and see what develops when you
type "mov dl, 1".)
Finally, I would like to point out that I have no idea what eax+30 holds in the above code. It
could either be the flag byte or perhaps a recordable flag. I don't know and I don't care,
either. Nor do I care how the code got to this point or where it goes from here. See, by
searching for the check itself ("and ???, 00000001"), we've eliminated possible hours of weaving
through the code and possibly being temporarily thwarted by false checks or thrown by other
anti-debugging tricks.
The audio tests I've checked work perfectly, though I've only tested about a dozen online radio
stations. So, I'm not guaranteeing success with everything, but it looks good so far. If
recording video clips interests you, it may or may not work. If not, perhaps trying a different
one of those "and" breakpoints will yield the answer.
Since I've enabled this record feature, I've enjoyed the ability to record clips "on the spot", as
I hear them. This is a big plus over using a utility like XFileGet to download clips. Also, Real
Player Plus G2 does an excellant job of buffering and recording only the music, not the blank spots.
The playback is smooth and I am finally a happy registered customer.
I wont even bother explaining you
that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this
software instead, you don't need to crack its protection scheme at all:
you'll find it on most Warez sites, complete and already regged,
farewell, don't come back.
You are deep inside fravia's page of reverse engineering,
choose your way out:
homepage
links
search_forms
+ORC
how to protect
academy database
reality cracking
how to search
java-script wars
tools
anonymity academy
cocktails
antismut CGI-scripts
mail_fravia+
Is reverse engineering legal?